JaneaSystems / nodejs-mobile

Full-fledged Node.js on Android and iOS
https://code.janeasystems.com/nodejs-mobile
Other
2.57k stars 183 forks source link

nodejs-project missing connection with currently active React Native bridge #143

Open staltz opened 5 years ago

staltz commented 5 years ago

Steps to reproduce the bug:

Expected behavior:

Heartbeats continue to be received at the UI JS side.

Actual behavior:

Heartbeats get lost (Calling JS function after bridge has been destroyed), logcat reports:

11-09 17:14:41.676 23616 23946 W unknown:ReactNative: Calling JS function after bridge has been destroyed: RCTNativeAppEventEmitter.emit(["nodejs-mobile-react-native-message",{"message":"heartbeat16"}","channelName":"_EVENTS_"}])

...

11-09 17:14:43.676 23616 23959 W unknown:ReactNative: Calling JS function after bridge has been destroyed: RCTNativeAppEventEmitter.emit(["nodejs-mobile-react-native-message",{"message":"heartbeat17"}","channelName":"_EVENTS_"}])

...

Notice also that the heartbeats are sent from the same process ID (23616, as expected) but different thread IDs (not expected, at least that's my impression).


Overall I'm concerned how the nodejs-project can transparently access always the "currently active" RN bridge, no matter if it was recreated upon development refresh, or if the nodejs-project lived in the background longer than the RN thread lived. I think some of the issues our app users are facing are related to this.

jaimecbernardo commented 5 years ago

Hi @staltz,

I've tried to replicate the issue, by adding the following lines at the end of the nodejs-project in this sample : https://github.com/janeasystems/nodejs-mobile-samples/blob/1eb9c4c0f1e02b009ca55bc610cc9e8cda403afa/react-native/UseMultipleChannels/nodejs-assets/nodejs-project/main.js#L140


let heartbeatNumber = 1;
setInterval( () => rn_bridge.channel.post('rn-log','Heartbeat ' + (heartbeatNumber++)), 1000);

Then, while the project is running, I've shaked the device and hit Reload. The heartbeats kept being received by the UI, so the bridge is reliably sending messages to the active UI, as far as I can observe.

If react-native destroys the UI there will be no actual "active" UI until a new UI is created and the messages sent in that interval will be lost. If the application depends on even those messages being delivered for sure, some sort of buffering/confirmation that the message was received could be built in the Application's protocol, but this could keep filling up the memory until react-native recreates the UI. Another way to do this could be by having the react-native Application send some signal to nodejs when the UI gets destroyed (if react-native has some handler for this).

I hope this was helpful.