xmpp.js
xmpp.js copied to clipboard
The xmpp is suspended by ios in background
When our application go into background, after a few minutes (it depends on phones), when we goback to the foreground, the xmpp is suspended, and we can not continue to send stanzard.
On Android, we call disconnect method to close the socket and it works. But on iphone, this method does not work.
Do you guys have any ideas about this issue. Thank in advance.
My idea: Don't use IOS device :)
If I remember correctly:
The problem is that iOS pauses all timeouts/intervals when the application goes to background and never resumes them. The solution is to disable reconnect before the app goes to background and re-enable it when the app goes foreground.
Something like
AppState.addEventListener('change', (appState) => {
if (appState === 'background' ) }
client.reconnect.stop();
} else if (appState === 'foreground') {
client.reconnect.start();
}
});
start
and stop
aren't documented, though, so this might break in a future release. If you fix the issue for yourself, please report back, and we can have a look at how to get this by default.
Hi @sonnyp thanks for your help. I try the reconnect.start() and stop() does not work on ios too, when we comeback to fg, the xmpp can not reconnect. For now, we are trying a solution to stop reduce the TCP keepalive on xmpp server, so that the socket will be stopped by timeout.
does not work on ios too, when we comeback to fg, the xmpp can not reconnect.
does not work
and xmpp can not reconnect
is not enough for me to help you. Please share code and precise observations.
The snippet I shared is just an example on top of my head, most likely, you'll have to tweak it. Perhaps consider using the inactive
app state. https://reactnative.dev/docs/appstate#app-states
Also xmpp isn't magically gonna reconnect if you disable reconnect. You need to start the connection after resuming. Try something like
AppState.addEventListener('change', (appState) => {
if (appState === 'background' ) }
client.stop(); // this might take too long try client.socket.close() as well
client.reconnect.stop();
} else if (appState === 'foreground') {
client.reconnect.start();
client.start();
}
});
Thanks Sonny. I tried client.stop(), it works fine but the delay is too long. I will try the connection.close in next steps. I checked inactive/background for sure, the reconnect stop/start does not work well. I greatly appreciate your help.
On Wed, Jul 7, 2021 at 4:24 PM Sonny Piers @.***> wrote:
does not work on ios too, when we comeback to fg, the xmpp can not reconnect.
does not work and xmpp can not reconnect is not enough for me to help you. Please share code and precise observations.
The snippet I shared is just an example on top of my head, most likely, you'll have to tweak it. Perhaps consider using the inactive app state. https://reactnative.dev/docs/appstate#app-states
Also xmpp isn't magically gonna reconnect if you disable reconnect. You need to start the connection after resuming. Try something like
AppState.addEventListener('change', (appState) => { if (appState === 'background' ) } client.stop(); // this might take too long try client.connection.close as well client.reconnect.stop(); } else if (appState === 'foreground') { client.reconnect.start(); client.start(); } });
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/xmppjs/xmpp.js/issues/902#issuecomment-875443512, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALE4YD5SXJCIVNSGFNZJKETTWQMM7ANCNFSM474UIXOQ .
@opentechiz did you find a workaround for the delay?
@samueldominguez the delay of stop and start again depends on the xmpp server too (how it authenticates the users, ..).
I am seeing some of this problem as well in my React Native app
After configuring the client and calling xmppClient.start()
I store the reference to xmppClient
in React Context, but sometimes I would find messages get sent out and lost with no response from the server, especially when coming back from background app state. Seems there are no error or disconnect events emitted by xmpp either in these rare cases...
My first approach was detecting background/inactive => active AppState and then trying to send presence to server to see if an ack stanza is received, but if 5 seconds pass with no ack, I call xmppClient.restart()
This did not seem to resolve the issue and it keeps happening occasionally. Sometimes coming back to foreground works fine with no extra logic needed so this bug is very hard to reproduce
My best guess is that since this library does not use NativeEventEmitter
that taps into native code and instead uses the npm events
package, maybe there is something about JS memory management that is disrupting the client's ability to reconnect and resume the stream. OS-level garbage collection may be taking over at a certain point and since this library was not originally built for mobile use, maybe there is more robust support needed here... Perhaps the use of react-native-events would help?
Now I am tweaking my xmppClient.send(xml('presence'))
solution and after my 5sec timeout of no ack from server, I am instead just calling xmppClient.stop()
and xmppClient.reconnect.stop()
and then totally rebuilding a new xmppClient
from scratch and storing it again in React Context.
I am hoping this works and doesn't cause memory leaks but would like to ask @sonnyp if there is a stronger way of making sure the old xmppClient
is totally destroyed from memory before rebuilding a new client?
will see how this goes...
will see how this goes...
@otech47 any updates? I'm interested in using this in a react native app...also for the chat display do you handle all that yourself or is there some react native library that does the heavy lifting?