davidliu
Committed by GitHub

Manually set connection state after reconnection (#130)

subscriber may not have disconnected and won't fire a connection state update
@@ -21,7 +21,7 @@ class PublisherTransportObserver( @@ -21,7 +21,7 @@ class PublisherTransportObserver(
21 } 21 }
22 22
23 override fun onRenegotiationNeeded() { 23 override fun onRenegotiationNeeded() {
24 - engine.negotiate() 24 + engine.negotiatePublisher()
25 } 25 }
26 26
27 override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState?) { 27 override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState?) {
@@ -150,7 +150,7 @@ internal constructor( @@ -150,7 +150,7 @@ internal constructor(
150 150
151 // create offer 151 // create offer
152 if (!this.isSubscriberPrimary) { 152 if (!this.isSubscriberPrimary) {
153 - negotiate() 153 + negotiatePublisher()
154 } 154 }
155 client.onReadyForResponses() 155 client.onReadyForResponses()
156 return joinResponse 156 return joinResponse
@@ -392,7 +392,7 @@ internal constructor( @@ -392,7 +392,7 @@ internal constructor(
392 // trigger publisher reconnect 392 // trigger publisher reconnect
393 // only restart publisher if it's needed 393 // only restart publisher if it's needed
394 if (hasPublished) { 394 if (hasPublished) {
395 - negotiate() 395 + negotiatePublisher()
396 } 396 }
397 } 397 }
398 // wait until ICE connected 398 // wait until ICE connected
@@ -408,8 +408,9 @@ internal constructor( @@ -408,8 +408,9 @@ internal constructor(
408 } 408 }
409 409
410 while (SystemClock.elapsedRealtime() < endTime) { 410 while (SystemClock.elapsedRealtime() < endTime) {
411 - if (connectionState == ConnectionState.CONNECTED) { 411 + if (subscriber.peerConnection.connectionState().isConnected()) {
412 LKLog.v { "reconnected to ICE" } 412 LKLog.v { "reconnected to ICE" }
  413 + connectionState = ConnectionState.CONNECTED
413 break 414 break
414 } 415 }
415 delay(100) 416 delay(100)
@@ -442,7 +443,7 @@ internal constructor( @@ -442,7 +443,7 @@ internal constructor(
442 } 443 }
443 } 444 }
444 445
445 - internal fun negotiate() { 446 + internal fun negotiatePublisher() {
446 if (!client.isConnected) { 447 if (!client.isConnected) {
447 return 448 return
448 } 449 }
@@ -481,7 +482,7 @@ internal constructor( @@ -481,7 +482,7 @@ internal constructor(
481 publisher.peerConnection.iceConnectionState() != PeerConnection.IceConnectionState.CHECKING 482 publisher.peerConnection.iceConnectionState() != PeerConnection.IceConnectionState.CHECKING
482 ) { 483 ) {
483 // start negotiation 484 // start negotiation
484 - this.negotiate() 485 + this.negotiatePublisher()
485 } 486 }
486 487
487 488
@@ -62,6 +62,7 @@ constructor( @@ -62,6 +62,7 @@ constructor(
62 62
63 private val responseFlow = MutableSharedFlow<LivekitRtc.SignalResponse>(Int.MAX_VALUE) 63 private val responseFlow = MutableSharedFlow<LivekitRtc.SignalResponse>(Int.MAX_VALUE)
64 64
  65 + var connectionState: ConnectionState = ConnectionState.DISCONNECTED
65 66
66 /** 67 /**
67 * @throws Exception if fails to connect. 68 * @throws Exception if fails to connect.
@@ -28,7 +28,6 @@ import org.mockito.Mockito @@ -28,7 +28,6 @@ import org.mockito.Mockito
28 import org.robolectric.RobolectricTestRunner 28 import org.robolectric.RobolectricTestRunner
29 import org.robolectric.Shadows.shadowOf 29 import org.robolectric.Shadows.shadowOf
30 import org.robolectric.shadows.ShadowConnectivityManager 30 import org.robolectric.shadows.ShadowConnectivityManager
31 -import org.robolectric.shadows.ShadowNetworkInfo  
32 31
33 @ExperimentalCoroutinesApi 32 @ExperimentalCoroutinesApi
34 @RunWith(RobolectricTestRunner::class) 33 @RunWith(RobolectricTestRunner::class)
@@ -346,4 +345,21 @@ class RoomMockE2ETest : MockE2ETest() { @@ -346,4 +345,21 @@ class RoomMockE2ETest : MockE2ETest() {
346 assertTrue(events[0] is RoomEvent.Reconnecting) 345 assertTrue(events[0] is RoomEvent.Reconnecting)
347 assertTrue(events[1] is RoomEvent.Reconnected) 346 assertTrue(events[1] is RoomEvent.Reconnected)
348 } 347 }
  348 +
  349 + @Test
  350 + fun reconnectFromWebSocketFailure() = runTest {
  351 + connect()
  352 +
  353 + val eventCollector = EventCollector(room.events, coroutineRule.scope)
  354 + wsFactory.onOpen = {
  355 + wsFactory.listener.onOpen(wsFactory.ws, createOpenResponse(wsFactory.request))
  356 + connectPeerConnection()
  357 + }
  358 + wsFactory.ws.cancel()
  359 + val events = eventCollector.stopCollecting()
  360 +
  361 + assertEquals(2, events.size)
  362 + assertTrue(events[0] is RoomEvent.Reconnecting)
  363 + assertTrue(events[1] is RoomEvent.Reconnected)
  364 + }
349 } 365 }