-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Fix connection drop is not detected #7825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1f19665
d1181e2
fc4a58c
3b52875
fa198f6
7ad9bc2
f5a0171
924ef7b
2e9eb22
8642da5
d9321c4
5cdc7ef
cfec1cd
17c519e
1d3536a
b327db8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,19 @@ | ||
| import _ from 'underscore'; | ||
| import NetInfo from './NetInfo'; | ||
| import NetInfo from '@react-native-community/netinfo'; | ||
| import AppStateMonitor from './AppStateMonitor'; | ||
| import promiseAllSettled from './promiseAllSettled'; | ||
| import Log from './Log'; | ||
| import * as Network from './actions/Network'; | ||
| import * as NetworkActions from './actions/Network'; | ||
| import * as NetowrkLib from './Network'; | ||
| import CONFIG from '../CONFIG'; | ||
| import CONST from '../CONST'; | ||
|
|
||
| // NetInfo.addEventListener() returns a function used to unsubscribe the | ||
| // listener so we must create a reference to it and call it in stopListeningForReconnect() | ||
| let unsubscribeFromNetInfo; | ||
| let unsubscribeFromAppState; | ||
| let isOffline = false; | ||
| let hasPendingNetworkCheck = true; | ||
|
|
||
| // Holds all of the callbacks that need to be triggered when the network reconnects | ||
| const reconnectionCallbacks = []; | ||
|
|
@@ -19,9 +23,9 @@ const reconnectionCallbacks = []; | |
| */ | ||
| const triggerReconnectionCallbacks = _.throttle((reason) => { | ||
| Log.info(`[NetworkConnection] Firing reconnection callbacks because ${reason}`); | ||
| Network.setIsLoadingAfterReconnect(true); | ||
| NetworkActions.setIsLoadingAfterReconnect(true); | ||
| promiseAllSettled(_.map(reconnectionCallbacks, callback => callback())) | ||
| .then(() => Network.setIsLoadingAfterReconnect(false)); | ||
| .then(() => NetworkActions.setIsLoadingAfterReconnect(false)); | ||
| }, 5000, {trailing: false}); | ||
|
|
||
| /** | ||
|
|
@@ -31,7 +35,7 @@ const triggerReconnectionCallbacks = _.throttle((reason) => { | |
| * @param {Boolean} isCurrentlyOffline | ||
| */ | ||
| function setOfflineStatus(isCurrentlyOffline) { | ||
| Network.setIsOffline(isCurrentlyOffline); | ||
| NetworkActions.setIsOffline(isCurrentlyOffline); | ||
|
|
||
| // When reconnecting, ie, going from offline to online, all the reconnection callbacks | ||
| // are triggered (this is usually Actions that need to re-download data from the server) | ||
|
|
@@ -47,21 +51,40 @@ function setOfflineStatus(isCurrentlyOffline) { | |
| * internet connectivity or not. This is more reliable than the Pusher | ||
| * `disconnected` event which takes about 10-15 seconds to emit. | ||
| */ | ||
| function listenForReconnect() { | ||
| Log.info('[NetworkConnection] listenForReconnect called'); | ||
| function subscribeToNetInfo() { | ||
| // Calling NetInfo.configure (re)checks current state. We use it to force a recheck whenever we (re)subscribe | ||
| NetInfo.configure({ | ||
| // By default, for web (including Electron) NetInfo uses `/` for `reachabilityUrl` | ||
| // When App is served locally or from Electron this would respond with OK even with no internet | ||
| // Using API url ensures reachability is tested over internet | ||
| reachabilityUrl: CONFIG.EXPENSIFY.URL_API_ROOT, | ||
| reachabilityTest: response => Promise.resolve(response.status === 200), | ||
|
|
||
| unsubscribeFromAppState = AppStateMonitor.addBecameActiveListener(() => { | ||
| triggerReconnectionCallbacks('app became active'); | ||
| // If a check is taking longer than this time we're considered offline | ||
| reachabilityRequestTimeout: CONST.NETWORK.MAX_PENDING_TIME_MS, | ||
| }); | ||
|
|
||
| // Subscribe to the state change event via NetInfo so we can update | ||
| // whether a user has internet connectivity or not. | ||
| unsubscribeFromNetInfo = NetInfo.addEventListener((state) => { | ||
| Log.info(`[NetworkConnection] NetInfo isConnected: ${state && state.isConnected}`); | ||
| setOfflineStatus(!state.isConnected); | ||
| Log.info('[NetworkConnection] NetInfo state change', false, state); | ||
| setOfflineStatus(state.isInternetReachable === false); | ||
|
|
||
| // When internet state is indeterminate a check is already running. Set the flag to prevent duplicate checks | ||
| hasPendingNetworkCheck = state.isInternetReachable === null; | ||
| }); | ||
| } | ||
|
|
||
| function listenForReconnect() { | ||
| Log.info('[NetworkConnection] listenForReconnect called'); | ||
|
|
||
| unsubscribeFromAppState = AppStateMonitor.addBecameActiveListener(() => { | ||
| triggerReconnectionCallbacks('app became active'); | ||
| }); | ||
|
|
||
| subscribeToNetInfo(); | ||
| } | ||
|
|
||
| /** | ||
| * Tear down the event listeners when we are finished with them. | ||
| */ | ||
|
|
@@ -86,6 +109,19 @@ function onReconnect(callback) { | |
| reconnectionCallbacks.push(callback); | ||
| } | ||
|
|
||
| function recheckNetworkConnection() { | ||
| if (hasPendingNetworkCheck) { | ||
| return; | ||
| } | ||
|
|
||
| Log.info('[NetworkConnection] recheck NetInfo'); | ||
| hasPendingNetworkCheck = true; | ||
| unsubscribeFromNetInfo(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kidroca Do you recall why you chose to unsubscribe and resubscribe to NetInfo rather than using NetInfo.fetch to recheck the network connection?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, looks like NetInfo will only trigger the recheck if you call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, there isn't an exposed way to force a recheck, it might not be necessary, though we decided to do it if any request is taking unusually long time (more than 10-15 sec) What triggers the recheck is actually the call to
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yep, I created a PR for react-native-netinfo to add this and clean up this implementation a bit: react-native-netinfo/react-native-netinfo#594 |
||
| subscribeToNetInfo(); | ||
| } | ||
|
|
||
| NetowrkLib.registerConnectionCheckCallback(recheckNetworkConnection); | ||
|
|
||
| export default { | ||
| setOfflineStatus, | ||
| listenForReconnect, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.