diff --git a/README.md b/README.md index 3b4fc44..4bd10af 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ const options: EventSourceOptions = { debug: false, // Show console.debug messages for debugging purpose. Default: false pollingInterval: 5000, // Time (ms) between reconnections. If set to 0, reconnections will be disabled. Default: 5000 lineEndingCharacter: null // Character(s) used to represent line endings in received data. Common values: '\n' for LF (Unix/Linux), '\r\n' for CRLF (Windows), '\r' for CR (older Mac). Default: null (Automatically detect from event) + reconnectOnActive: true, // Automatically reconnect when the app becomes active (e.g., after being in the background) Default: False } ``` diff --git a/index.d.ts b/index.d.ts index eb77c42..d144022 100644 --- a/index.d.ts +++ b/index.d.ts @@ -50,6 +50,7 @@ export interface EventSourceOptions { debug?: boolean; pollingInterval?: number; lineEndingCharacter?: string; + reconnectOnActive?: boolean; } type BuiltInEventMap = { diff --git a/src/EventSource.js b/src/EventSource.js index 6a7b146..9ab6b76 100644 --- a/src/EventSource.js +++ b/src/EventSource.js @@ -1,3 +1,5 @@ +import { AppState } from 'react-native'; + const XMLReadyStateMap = [ 'UNSENT', 'OPENED', @@ -36,11 +38,16 @@ class EventSource { this.debug = options.debug || false; this.interval = options.pollingInterval ?? 5000; this.lineEndingCharacter = options.lineEndingCharacter || null; + this.reconnectOnActive = options.reconnectOnActive || false; this._xhr = null; this._pollTimer = null; this._lastIndexProcessed = 0; + this._appStateSubscription = null; + this._setupAppStateListener(); + + if (!url || (typeof url !== 'string' && typeof url.toString !== 'function')) { throw new SyntaxError('[EventSource] Invalid URL argument.'); } @@ -54,6 +61,28 @@ class EventSource { this._pollAgain(this.timeoutBeforeConnection, true); } + _setupAppStateListener() { + this._appStateSubscription = AppState.addEventListener( + 'change', + this._handleAppStateChange + ); + } + + _handleAppStateChange = (nextAppState) => { + if (nextAppState === 'active') { + this._logDebug('[EventSource] App became active, reconnecting...'); + this.close(); + if (this.reconnectOnActive) { + this._pollAgain(0, true); // reconnect if the option is enabled + } + } else if (nextAppState === 'background' || nextAppState === 'inactive') { + this._logDebug( + '[EventSource] App went to background, closing connection...' + ); + this.close(); + } + }; + _pollAgain(time, allowZero) { if (time > 0 || allowZero) { this._logDebug(`[EventSource] Will open new connection in ${time} ms.`); @@ -313,7 +342,12 @@ class EventSource { if (this._xhr) { this._xhr.abort(); } + + if (this._appStateSubscription) { + this._appStateSubscription.remove(); + this._appStateSubscription = null; + } } } -export default EventSource; +export default EventSource; \ No newline at end of file