client-sdk-swift icon indicating copy to clipboard operation
client-sdk-swift copied to clipboard

ConnectionState does not match the connection state within LivekitSDK (didUpdateConnectionState not updating)

Open michaelbutler1998 opened this issue 1 year ago • 9 comments

Describe the bug

connectionState still appears to be .connected (didUpdateConnectionState is not called to alert about .disconnect) when you lose connection for a prolonged period (around 15+ seconds), but the LiveKitSDK can see that you should be in .disconnected

SDK Version 2.0.5

iOS Version 17.4.1

Steps to Reproduce

  1. Join a call, with another participant active and listening
  2. Turn off your cellular network for 15 seconds.

Whilst you're in this state you can see livekit logs (see log #1 below). When checking connectionState from room, connectionState == .connected.

didUpdateConnectionState is not called to notify that state is now .disconnected

  1. Quickly, toggle mute / unmute when cellular is back on

You now end up in a situation where the listening user cannot hear or communicate with you. If the listening user, or the glitched user rejoins, you can hear each other again.

Expected behavior

  1. During the reconnect, the state should be .reconnecting
  2. connectionState is updated when Livekit is aware of .disconnection, so that we can prevent users from turning their mic on/off when not connected

Logs Please provide logs if you can.

Log #1 - \`\`\`
2024-04-19T14:23:14+0100 error LiveKitSDK : \[LiveKit\] SignalClient.*sendRequest(*:) connectionState is .disconnected
2024-04-19T14:23:14+0100 error LiveKitSDK : \[LiveKit\] Engine.transport(\_:didGenerateIceCandidate:) Failed to send iceCandidate, error: Error Domain=io.livekit.swift-sdk Code=104 "Invalid state(connectionState is .disconnected)" UserInfo={NSLocalizedDescription=Invalid state(connectionState is .disconnected)}

michaelbutler1998 avatar Apr 19 '24 14:04 michaelbutler1998

I want to point out that I receive reconnecting logs but the state remain connected while being offline. This might be related.

buttjer avatar Apr 19 '24 14:04 buttjer

Possibly related bug:

  1. Connect to call with two phones, cellular only on 4G/5G.
  2. With one phone, in your phone's settings, set your connection to 2G
  3. Whilst in 2G, toggle your microphone
  4. Change your phones settings back to 4G
  5. Attempt to communicate / toggle mic etc.

You cannot be heard by the other participant, the same as in the initial bug report.

If you are not using Callkit, you get this error: 2024-04-19T17:16:34+0100 error LiveKitSDK : [LiveKit] Engine.signalClient(_:didReceiveAnswer:) Failed to set remote description, error: Error Domain=org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection) Code=-1 "Failed to set remote answer sdp: Called in wrong state: stable" UserInfo={NSLocalizedDescription=Failed to set remote answer sdp: Called in wrong state: stable}

If you are using Callkit, you get this error: 2024-04-19T16:29:06+0100 error LiveKitSDK : [LiveKit] AudioManager.defaultConfigureAudioSessionFunc(newState:oldState:) Failed to configure audio session with error: Error Domain=NSOSStatusErrorDomain Code=1701737535 "Session activation failed" UserInfo={NSLocalizedDescription=Session activation failed}

michaelbutler1998 avatar Apr 19 '24 16:04 michaelbutler1998

You are watching logs for SignalClient(WebSocket)'s connectionState, instead of Engine's connectionState. The didUpdateConnectionState delegate should match the Engine's connectionState. The SDK finally reports disconnect after several attempts to reconnect the internal SignalClient etc.

Example turning off cellular & wifi on iPhone : C2AA33AE-ECDB-4213-A8E1-CF2A91B2B6DD

Quickly, toggle mute / unmute when cellular is back on You now end up in a situation where the listening user cannot hear or communicate with you. If the listening user, or the glitched user rejoins, you can hear each other again.

This is another issue I will try to reproduce.

hiroshihorie avatar Apr 22 '24 04:04 hiroshihorie

@hiroshihorie

Thanks for the quick response!

This is how we mute await self.room.localParticipant.unpublishAll()

and unmute try await self.room.localParticipant.setMicrophone(enabled: true)

buttjer avatar Apr 22 '24 08:04 buttjer

Can you try try await self.room.localParticipant.setMicrophone(enabled: false) to mute instead ?

This method is guaranteed to execute exclusively when invoked asynchronously .

hiroshihorie avatar Apr 22 '24 09:04 hiroshihorie

@hiroshihorie just tried with this suggestion, however the same issue still occurs unfortunately

Can you try try await self.room.localParticipant.setMicrophone(enabled: false) to mute instead ?

michaelbutler1998 avatar Apr 22 '24 09:04 michaelbutler1998

@michaelbutler1998 Will start investigating this one. It only happens while (internal) reconnecting ?

hiroshihorie avatar Apr 23 '24 07:04 hiroshihorie

@michaelbutler1998 Will start investigating this one. It only happens while (internal) reconnecting ?

Sorry I don't know for certain, I have only seen it occur when switching back and forth from 2G

michaelbutler1998 avatar Apr 23 '24 08:04 michaelbutler1998

@hiroshihorie any luck with this issue?

michaelbutler1998 avatar May 10 '24 08:05 michaelbutler1998