ConnectyCube / connectycube-cordova-samples

Cordova code samples for ConnectyCube platform
https://connecycube.com
Apache License 2.0
4 stars 5 forks source link

Video calls not working after app was switched to background mode. #2

Closed vo-va closed 4 years ago

vo-va commented 4 years ago

I have a working prototype. But after I will lock my phone it stop working. I need to restart app to force it working again.

I am guessing that device OS stop/close network connections and ConnectyCube require new initialisation. I've tried to use Cordova event resume to execute ConnectyCube.chat.connect(...) when app being switched from background to foreground mode, but this not helping. Maybe I am missing something.

Please share a receipt for described situation. Also can you share not obfuscated main.js. I am guessing it is obfuscated because comes with library code. Maybe you can separate library code in different file and inmain.js leave only app code.

Errors that I see in JS console after app was switched from background to foreground mode (Actually I am doing lock/unlock) Screenshot from 2020-05-28 00-22-11

vo-va commented 4 years ago

For now I ended up with manually removing all event listeners and initialising connection to ConnectyCube again on cordova resume event

ConnectyCube.videochat.onCallListener = undefined;
ConnectyCube.videochat.onAcceptCallListener = undefined;
ConnectyCube.videochat.onRejectCallListener = undefined;
ConnectyCube.videochat.onStopCallListener = undefined;
ConnectyCube.videochat.onUserNotAnswerListener = undefined;
ConnectyCube.videochat.onRemoteStreamListener = undefined;
ConnectyCube.videochat.onDevicesChangeListener = undefined;

...

ConnectyCube.chat.connect(...)

I think it is would be better to use

ConnectyCube.chat.disconnect();
ConnectyCube.destroySession();

but I didn't tested it yet.

@ccvlad @DaveLomber may I ask you what is the proper way to restore/reconnect session to ConnectyCube servers after phone was locked/app switched to background?

vo-va commented 4 years ago

Tested

ConnectyCube.chat.disconnect();
ConnectyCube.destroySession();

It is not working image

Because when this function is being called this.parser is null or undefined and e.once() failing image because e is null

DaveLomber commented 4 years ago

Hi @vo-va thank you for reporting the issue

Here is a ref to same issue for Web https://github.com/ConnectyCube/connectycube-js-sdk-releases/issues/28#issuecomment-636039403

and the fix is going to be pushed during next 1-2 days

I will update here

vo-va commented 4 years ago

@DaveLomber sorry to bother you again. First of all thank you for update. And second can you confirm that

ConnectyCube.chat.disconnect();
ConnectyCube.destroySession();

is the proper way to restore connection to ConnectyCube servers after app was switched to background mode?

DaveLomber commented 4 years ago

@vo-va Actually you can do it,

but it's completely not required to kill chat connection and destroy session

What we mainly recommend is to just call one thing, as listed here: https://developers.connectycube.com/js/messaging?id=mark-a-client-as-activeinactive

This will help a server to initiate automatic push notifications for chat messages

But it's not related to calling functionality. So what I recommend is do nothing when you switch to BG.

And only check in FG do you need to restore chat connection or not, something like this:

ConnectyCube.chat.onDisconnectedListener = onDisconnectedListener;

function onDisconnectedListener() {
    isConnected = false;
}

...

function onSwitchToForeground() {
   if (!isConnected) {
      ConnectyCube.chat.connect(...)
   }
}
DaveLomber commented 4 years ago

@vo-va SDK 3.1.0 is published with a fix to jid._local crash

Please upgrade and test https://github.com/ConnectyCube/connectycube-js-sdk-releases/releases/tag/3.1.0

vo-va commented 4 years ago

@DaveLomber

I've tested receipt with using variable to store state of connection, and change it with callback onDisconnectedListener(). It does not work reliably in all cases. For example if I lock phone, and turn off wifi then in JS console I see next error, and callback does not change variable state to false (disconnected).

vendor.32ce9d973dd0e671db69.js:12 Uncaught TypeError: The "listener" argument must be of type Function. Received type object
    at e.exports.a.removeListener (connectycube.min.js:1)
    at connectycube.min.js:1
    at Array.forEach (<anonymous>)
    at i._detachSocket (connectycube.min.js:1)
    at i._reset (connectycube.min.js:1)
    at e.exports.n.close (connectycube.min.js:1)
    at e.exports.a.emit (connectycube.min.js:1)
    at WebSocket.n.close (connectycube.min.js:8)
    at WebSocket.r (vendor.32ce9d973dd0e671db69.js:12)

To mitigate this, I've tried to catch exceptions for simple functions like this ConnectyCube.chat.markActive(); or ConnectyCube.chat.dialog.list(). No luck In JS console I'am seeing errors about Uncaught (in promise)...

So since I can't reliably detect current state of connection - I am recreating it each time when application switched to foreground mode.

ConnectyCube.chat.disconnect();
ConnectyCube.destroySession();

ConnectyCube.initConnectyCube();
ConnectyCube.chat.connect();

This lead me to other issue, if I will not destroy previous session then during incoming calls I am seeing debug notification about unknown/duplicate of sessions. So I am destroying and creating it it each time, even when session tokens not expired yet

Because of this other edge case issue. I can't check if session token, that I have in application memory or in browser local storage, valid or not.

ConnectyCube.initConnectyCube(); does not throw anything if session invalid.

ConnectyCube.chat.connect(); throw next exception, and I can't catch it.

connectycube.min.js:1 Uncaught (in promise) SASLError: not-authorized - Password not verified
    at Function.fromElement (file:///android_asset/www/static/connectycube.min.js:1:25740)
    at i.a (file:///android_asset/www/static/connectycube.min.js:8:45404)
    at i.a.emit (file:///android_asset/www/static/connectycube.min.js:1:20170)
    at i._onElement (file:///android_asset/www/static/connectycube.min.js:1:27917)
    at e.exports.a.emit (file:///android_asset/www/static/connectycube.min.js:1:20170)
    at e.exports.onEndElement (file:///android_asset/www/static/connectycube.min.js:8:38040)
    at e.exports.a.emit (file:///android_asset/www/static/connectycube.min.js:1:20170)
    at e.exports._handleTagOpening (file:///android_asset/www/static/connectycube.min.js:8:32813)
    at e.exports.write (file:///android_asset/www/static/connectycube.min.js:8:33850)
    at e.exports.write (file:///android_asset/www/static/connectycube.min.js:1:34199)
    at i._onData (file:///android_asset/www/static/connectycube.min.js:1:27278)
    at e.exports.a.emit (file:///android_asset/www/static/connectycube.min.js:1:20170)
    at WebSocket.n.message (file:///android_asset/www/static/connectycube.min.js:8:36965)
    at WebSocket.r (file:///android_asset/www/static/js/vendor.32ce9d973dd0e671db69.js:12:157926)

This is another reason why I have to create new session token each time.

Other edge case when I would like to catch error, but can't. If I will open session on phone, lock it, open session on other device. Then on wake up application on the first phone existed session will be invalid and ConnectyCube.chat.connect(); will throw same exception as previous.

I am guessing that exception I am seeing is a bugs, but if not please help me to understand how to use ConnecyCube library. Basically I need reliable option to detect if connection to ConnectyCbue servers is live. And second, I need option to detect if credentials (session token) expired, so I can use next approach. Use session token from memory and if it is not valid then request a new one.

DaveLomber commented 4 years ago

@vo-va Thanks for providing the reliable feedback let us check the 'Uncaught TypeError' issue at our end and get back to you

DaveLomber commented 4 years ago

@vo-va seems the issue comes from here https://github.com/xmppjs/xmpp.js/blob/master/packages/connection/index.js#L91

and I'm not fully clear re reason

DaveLomber commented 4 years ago

Just to clarify the steps

should we just do the following to reproduce it? 1) connect to chat 2) go to BG 3) disconnect internet

vo-va commented 4 years ago

yes, the steps are correct.

To reproduce other issue that I had

  1. establish chat connection (probably not necessary)
  2. disconnect internet
  3. on other device create new session, and destroy old sessions (I am doing this so the device that reconnected does not have many sessions)
  4. connect to internet on the first device
  5. Initialise ConnectyCube.initConnectyCube(); with old (already destroyed) session token - no error/excetion
  6. try to do chat connect - exception that I can't catch.
vo-va commented 4 years ago

Hi @DaveLomber Just wondering do you have any updates? Did you manage to reproduce my issues?

ccvlad commented 4 years ago

Closed due to inactivity. Please re-open if the issue is still persists.