client-sdk-react-native icon indicating copy to clipboard operation
client-sdk-react-native copied to clipboard

Auto disconnect fails after screen lock/unlock

Open arekkubaczkowski opened this issue 1 year ago • 3 comments

Describe the bug

I am experiencing an issue when I lock the phone screen during an active live session and then unlock it to return to that session.

Steps to reproduce:

  • Open a live session as a viewer.
  • Lock the screen.
  • From another device as the host, close the session.
  • Unlock the screen.
  • At this point, the user should be disconnected automatically, but this does not happen despite the on.disconnect listener being implemented, which should trigger navigation.back.

I suspect that onDisconnect is not being called because the app is in a background at that point. I am looking for any solution that would allow to identify the connection status after coming back to the app so I can take user from that screen.

useEffect(() => {
    const handleDisconnected = () => {
      router.back();
    };

    room.on('disconnected', handleDisconnected);

    return () => {
      room.off('disconnected', handleDisconnected);
    };
  }, [room, router]);

Screenshots

Device Info:

  • Device: iPhone 15 Pro
  • OS: 17.5.1

Dependencies Info (please reference your package-lock.json or yarn.lock file):

  • @livekit/react-native: 2.3.1
  • livekit-client: 2.0.10 (fetched by @livekit/react-native)
  • react-native-webrtc: 114.1.6

arekkubaczkowski avatar Jun 26 '24 13:06 arekkubaczkowski

I would be really grateful for any help regarding this.

arekkubaczkowski avatar Jul 10 '24 06:07 arekkubaczkowski

I am still having this issue :(

arekkubaczkowski avatar Nov 28 '24 05:11 arekkubaczkowski

I believe we came across a similar issue - in our case answering a call would keep the screen locked which would stop callee from joining a call.

The root cause appears to be how OS handles setTimeout and setInterval - if screen is locked none of the callbacks will execute and client-sdk-react-native relies heavily on livekit-client which uses both functions a lot. After a bit more digging I found that probably for exactly this reason livekit-client offers CriticalTimers doc.

I have overwritten these using react-native-background-timer, e.g:

CriticalTimers.setTimeout = (callback, ms) => {
  return BackgroundTimer.setTimeout(callback, ms);
}

CriticalTimers.setInterval = (callback, ms) => {
  return BackgroundTimer.setInterval(callback, ms);
}
// etc

and that almost resolved the issue but the audio sample would be only one-way - callee would receiver caller but not the opposite. Doing a bit more digging led me to this negotiate call which uses 3rd-party ts-debounce. ts-debounce uses setTimeout which again doesn't run if a screen is locked. I don't know if it is required during reconnection but when initialising a call, this needs to run for both sides to correctly establish the connection. Getting rid of debounce wrapper fixes the problem but that's just a short-term solution

jankosecki avatar Jan 13 '25 12:01 jankosecki