Skip to content
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

The xmpp is suspended by ios in background #902

Open
opentechiz opened this issue Jul 6, 2021 · 9 comments
Open

The xmpp is suspended by ios in background #902

opentechiz opened this issue Jul 6, 2021 · 9 comments

Comments

@opentechiz
Copy link

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.

@nghuyy
Copy link

nghuyy commented Jul 6, 2021

My idea:
Don't use IOS device :)

@sonnyp
Copy link
Member

sonnyp commented Jul 6, 2021

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.

@opentechiz
Copy link
Author

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.

@sonnyp
Copy link
Member

sonnyp commented Jul 7, 2021

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();
  }
});

@opentechiz
Copy link
Author

opentechiz commented Jul 7, 2021 via email

@samueldominguez
Copy link

@opentechiz did you find a workaround for the delay?

@opentechiz
Copy link
Author

@samueldominguez the delay of stop and start again depends on the xmpp server too (how it authenticates the users, ..).

@otech47
Copy link

otech47 commented Mar 7, 2023

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...

Screenshot 2023-03-07 at 2 24 35 PM

@timothyerwin
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants