I’m building a React Native app using mediasoup-client v3 for real-time audio/video. I’m running into a scenario where I need guidance on persistent sessions across JS restarts.
Scenario
The app is in an active call with mediasoup:
Device loaded
SendTransport / RecvTransport created
Producer and Consumer objects active
Local MediaStreamTracks for audio/video in use
We have a foreground service running on Android that keeps the native WebRTC session alive when the app goes into background or is removed from recents.
While the app is gone:
Audio/video continues to flow
Native transports, producers, consumers, and media tracks remain alive
JS layer is destroyed — all React state, mediasoup-client objects, and references are lost
When the app is reopened, we lose all JS references, even though the underlying native session is still active.
Questions
Has anyone implemented persistent mediasoup sessions in React Native where JS can rebind to existing native Transports, Producers, Consumers, and MediaStreamTracks after restart?
Does mediasoup-client provide any mechanism to “rehydrate” or reconnect to existing native objects, or is rebuilding from scratch the only option?
What are the best practices / architecture patterns for bridging a persistent native mediasoup session to React Native JS, so that:
Media continues uninterrupted
UI and event listeners can reconnect seamlessly
JS does not have to create new transports/producers/consumers unnecessarily
In production apps with persistent calls (Zoom, WhatsApp, etc.), do they rebuild everything on JS restart, or do they maintain a native session and reattach the UI?
Any examples, code patterns, or experience sharing for this kind of persistent session recovery in React Native + mediasoup would be hugely appreciated.
Regarding mediasoup-client Transports, Producers and Consumers you can intercept their corresponding “connect”, “produce” and “consume” events and, instead of sending a message to the server, auto-answer their callback with the data you have stored in your foreground service, so those classes are created in JS land in your app with same internal values as before.
Regarding MediaStreamTracks no idea because they depend on react-native-webrtc.
You could possibly use WebAssembly as a state-holder, the JS then can become hot-swappable.
As mentioned previously, there’s the callbacks, but in this case, server could ping the user to update client, state remains in webassembly and when logic reloads it can go back to where it was exactly. You wouldn’t need to end connection with chat server or anything of the sort. If chat server updates though that’s a different scenario and recovery handling. Different topic for that one.
Consider proper error handling if there’s any issues to ensure client will eventually get resolved in minutes, upon refresh or something as a good fallback incase.
but React Native JS runtime is killed when the app is removed from recents. will the webassembly code live through this scenario? As far as i know the the webassembly memory also get cleared when the app is removed from the recents. Only the native storage is persisted if a foreground sevice is running.
We are using react native webrtc and mediasoupclint libs. We can be in a call in android even after the app is removed from background by running a foreground service and we can listen socket events in native android side. But how do we handle when new participant i.e new producer joined when apps js thread isn’t alive?
Is the only solution using native-android mediasoup client module and share the state b/w js and native side?