voximplant / react-native-voximplant

Voximplant mobile SDK for React Native (iOS/Android)
http://voximplant.com
205 stars 39 forks source link

Call disconnects for one user but times out after 30 seconds for the other #79

Open sanjaypojo opened 5 years ago

sanjaypojo commented 5 years ago

Hi @YuliaGrigorieva,

As you know, we've been investigating connection issues and we have isolated a problem that you can reproduce:

The socket to "A" has probably broken, but no event is emitted. Would it be possible to emit an event, so that we can update the screen to say user disconnected, attempting to reconnect etc.?

leon2835 commented 5 years ago

Same issue, any solution on it? Unable to get "Disconnect" response whenever 1 of the device hang/decline the call.

YuliaGrigorieva commented 5 years ago

Hello @sanjaypojo ,

The scenario that you have described works as intended. When one of the clients lost the connection to the Voximplant Cloud during a call, the Voximplant Cloud has a 30 seconds timeout to detect the client is no more connected. Another client (client "A" is your case) still have a connection to the Voximplant Cloud and receives a call disconnected event after 30 seconds timeout.

This 30 seconds timeout is not configurable, however you can implement the following logic to detect connection issues on client "B" and hang up the call on the client "A".

  1. Use Call.sendMessage API to send some messages periodically during a call between the clients to notify them that their are alive.
  2. Choose an appropriate timeout to receive the message
  3. If one of the clients does not receive your message, you can hang up the call.

Best regards, Yulia Grigorieva

YuliaGrigorieva commented 5 years ago

Hello @leon2835 ,

It seems you have faced a different issue.

Using Call.hangup or Call.decline should always produce the call disconnected/failed event if the clients are connected the Voximplant Cloud.

Please provide more information about your issue.

Best regards, Yulia Grigorieva

sanjaypojo commented 5 years ago

Hi @YuliaGrigorieva, thanks for the suggestion. I'd like to better understand how Call.sendMessage works:

bfelbo commented 3 years ago

This 30 seconds timeout is not configurable, however you can implement the following logic to detect connection issues on client "B" and hang up the call on the client "A".

  1. Use Call.sendMessage API to send some messages periodically during a call between the clients to notify them that their are alive.
  2. Choose an appropriate timeout to receive the message
  3. If one of the clients does not receive your message, you can hang up the call.

Hi @YuliaGrigorieva, this issue is causing us a lot of pain and implementing the suggested heartbeat logic would add a lot of complexity to our code. We're using Voximplant precisely to keep our code simple. Would it be possible to prioritize fixing this issue on the Voximplant side?

YuliaGrigorieva commented 3 years ago

Hello @sanjaypojo, @bfelbo,

I have discussed this issue with the team. As an option we can implement an event that will notify that there is no incoming audio traffic in a call.

Please let me know if this option is convenient for you.

Best regards, Yulia Grigorieva

sanjaypojo commented 3 years ago

Hi @YuliaGrigorieva that sounds great! I wanted to check if I understood this correctly:

For my understanding, could you explain why the FAILED event is not triggered immediately and we're using a different event in this scenario? Is this because voximplant will try to "reconnect" the call somehow for 30 seconds?

Thanks a lot! Excited for your help on this :)

YuliaGrigorieva commented 3 years ago

Hello @sanjaypojo,

I see the following cases:

  1. the call is connected between A and B before the internet is turned off on B

Both clients should receive CallDisconnected event. The client A (with the internet connection) will receive it after ~30 seconds the client B lost the connection. Client B will receive it immediately with the ClientDisconnected event (ClientDisconnected event informs that the connection to the Voximplant Cloud is closed).

  1. the call is not connected between A and B before the internet is turned off on B

Both clients should receive CallFailed event as the call is not connected. B will receive it immediately with the ClientDisconnected event , A will receive CallFailed event after a standard timeout given to answer a call.

  1. the call is not connected between A and B before the internet is turned off on B, but B has answered the call and SDK has notified the Voximplant Cloud that the call was answered.

The client B will receive CallFailed event immediately with the ClientDisconnected event. Client A most likely will receive CallDisconnected event because client B has sent the information about the call answer and the negotiation is completed, but not the ICE connection (for p2p calls)


The proposed solution is for the first case and probably for the third case. The event that I propose will be based on the call stats that is collected only if the call is connected. As for the second case, this is the expected behavior. It is worth to note that behavior in this case also depends if the client B received IncomingCall event or not. If it is offline when the client A makes a call, client A will receive CallFailed immediately (assuming the push notifications are not enabled). If you have any issues with this case, we can discuss it in details.

Answering your questions about this proposed solution:

When audio traffic stops an event is emitted immediately.

Not immediately, but in 1-2 seconds. Call stats are collected with 500ms interval and I suppose it will require the analysis of 2-4 stats frames to detect that the traffic has stopped.

30 seconds later, the call normally fails with a FAILED event.

In ~30 seconds the client should receive CallDisconnected event.

For my understanding, could you explain why the FAILED event is not triggered immediately and we're using a different event in this scenario? Is this because voximplant will try to "reconnect" the call somehow for 30 seconds?

The SDK uses web sockets to communicate with the Cloud. When the internet is turned off the socket is not closed properly by OS, it cannot notify the Cloud that the connection is closed because the connection is already closed. The Cloud detects the connection issue by its timeouts that are ~30 seconds.


At this point, I think we need to clarify the case, as you mention that you receive Failed event, but it should not happen in the first case I described.

Best regards, Yulia Grigorieva

sanjaypojo commented 3 years ago

@YuliaGrigorieva thanks for the detailed response. What we would like to detect is not when the voximplant socket disconnects, but when the p2p call disconnects / doesn't have audio flowing successfully. Would it be possible to monitor this directly on each client?

(1) We currently use Voximplant.CallEvents.ICETimeout. How long is the ICETimeout duration? Would it be possible to control this duration?

(2) In this scenario: Two clients A & B are connected on voice chat. B puts on airplane mode. This should disconnect both the p2p call as well as the voximplant socket. Is it possible for A to detect the disconnection of the p2p call instantly? This is the event we'd like to have. Ideally, this event should be detected fully client side without involving the voximplant socket.

(3) Just to understand, what is the difference between the Connected and ICEConnected event. In what order do they occur and when does audio start flowing?

Thanks so much!