Auto disconnect fails after screen lock/unlock
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
I would be really grateful for any help regarding this.
I am still having this issue :(
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