Committed by
GitHub
Clean up room and local participant between sessions (#196)
正在显示
6 个修改的文件
包含
126 行增加
和
13 行删除
| @@ -458,6 +458,10 @@ constructor( | @@ -458,6 +458,10 @@ constructor( | ||
| 458 | localParticipant.cleanup() | 458 | localParticipant.cleanup() |
| 459 | remoteParticipants.keys.toMutableSet() // copy keys to avoid concurrent modifications. | 459 | remoteParticipants.keys.toMutableSet() // copy keys to avoid concurrent modifications. |
| 460 | .forEach { sid -> handleParticipantDisconnect(sid) } | 460 | .forEach { sid -> handleParticipantDisconnect(sid) } |
| 461 | + | ||
| 462 | + sid = null | ||
| 463 | + metadata = null | ||
| 464 | + name = null | ||
| 461 | } | 465 | } |
| 462 | 466 | ||
| 463 | private fun handleDisconnect(reason: DisconnectReason) { | 467 | private fun handleDisconnect(reason: DisconnectReason) { |
| @@ -143,15 +143,19 @@ open class Participant( | @@ -143,15 +143,19 @@ open class Participant( | ||
| 143 | 143 | ||
| 144 | private fun Flow<Map<String, TrackPublication>>.trackUpdateFlow(): Flow<List<Pair<TrackPublication, Track?>>> { | 144 | private fun Flow<Map<String, TrackPublication>>.trackUpdateFlow(): Flow<List<Pair<TrackPublication, Track?>>> { |
| 145 | return flatMapLatest { videoTracks -> | 145 | return flatMapLatest { videoTracks -> |
| 146 | - combine( | ||
| 147 | - videoTracks.values | ||
| 148 | - .map { trackPublication -> | ||
| 149 | - // Re-emit when track changes | ||
| 150 | - trackPublication::track.flow | ||
| 151 | - .map { trackPublication to trackPublication.track } | ||
| 152 | - } | ||
| 153 | - ) { trackPubs -> | ||
| 154 | - trackPubs.toList() | 146 | + if (videoTracks.isEmpty()) { |
| 147 | + flowOf(emptyList()) | ||
| 148 | + } else { | ||
| 149 | + combine( | ||
| 150 | + videoTracks.values | ||
| 151 | + .map { trackPublication -> | ||
| 152 | + // Re-emit when track changes | ||
| 153 | + trackPublication::track.flow | ||
| 154 | + .map { trackPublication to trackPublication.track } | ||
| 155 | + } | ||
| 156 | + ) { trackPubs -> | ||
| 157 | + trackPubs.toList() | ||
| 158 | + } | ||
| 155 | } | 159 | } |
| 156 | } | 160 | } |
| 157 | } | 161 | } |
| @@ -309,6 +313,14 @@ open class Participant( | @@ -309,6 +313,14 @@ open class Participant( | ||
| 309 | 313 | ||
| 310 | internal open fun dispose() { | 314 | internal open fun dispose() { |
| 311 | scope.cancel() | 315 | scope.cancel() |
| 316 | + | ||
| 317 | + sid = "" | ||
| 318 | + name = null | ||
| 319 | + identity = null | ||
| 320 | + metadata = null | ||
| 321 | + participantInfo = null | ||
| 322 | + permissions = null | ||
| 323 | + connectionQuality = ConnectionQuality.UNKNOWN | ||
| 312 | } | 324 | } |
| 313 | } | 325 | } |
| 314 | 326 |
| @@ -16,6 +16,7 @@ import io.livekit.android.room.track.Track | @@ -16,6 +16,7 @@ import io.livekit.android.room.track.Track | ||
| 16 | import io.livekit.android.util.flow | 16 | import io.livekit.android.util.flow |
| 17 | import io.livekit.android.util.toOkioByteString | 17 | import io.livekit.android.util.toOkioByteString |
| 18 | import junit.framework.Assert.assertEquals | 18 | import junit.framework.Assert.assertEquals |
| 19 | +import junit.framework.Assert.assertNull | ||
| 19 | import kotlinx.coroutines.ExperimentalCoroutinesApi | 20 | import kotlinx.coroutines.ExperimentalCoroutinesApi |
| 20 | import kotlinx.coroutines.launch | 21 | import kotlinx.coroutines.launch |
| 21 | import org.junit.Assert | 22 | import org.junit.Assert |
| @@ -290,8 +291,9 @@ class RoomMockE2ETest : MockE2ETest() { | @@ -290,8 +291,9 @@ class RoomMockE2ETest : MockE2ETest() { | ||
| 290 | ) | 291 | ) |
| 291 | val events = eventCollector.stopCollecting() | 292 | val events = eventCollector.stopCollecting() |
| 292 | 293 | ||
| 293 | - Assert.assertEquals(1, events.size) | ||
| 294 | - Assert.assertEquals(true, events[0] is RoomEvent.Disconnected) | 294 | + assertEquals(1, events.size) |
| 295 | + assertEquals(true, events[0] is RoomEvent.Disconnected) | ||
| 296 | + | ||
| 295 | } | 297 | } |
| 296 | 298 | ||
| 297 | @Test | 299 | @Test |
| @@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow | @@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow | ||
| 16 | import kotlinx.coroutines.flow.SharedFlow | 16 | import kotlinx.coroutines.flow.SharedFlow |
| 17 | import kotlinx.coroutines.test.runTest | 17 | import kotlinx.coroutines.test.runTest |
| 18 | import org.junit.Assert | 18 | import org.junit.Assert |
| 19 | -import org.junit.Assert.assertEquals | 19 | +import org.junit.Assert.* |
| 20 | import org.junit.Before | 20 | import org.junit.Before |
| 21 | import org.junit.Rule | 21 | import org.junit.Rule |
| 22 | import org.junit.Test | 22 | import org.junit.Test |
| @@ -128,7 +128,7 @@ class RoomTest { | @@ -128,7 +128,7 @@ class RoomTest { | ||
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | @Test | 130 | @Test |
| 131 | - fun onDisconnect() = runTest { | 131 | + fun onServerLeave() = runTest { |
| 132 | connect() | 132 | connect() |
| 133 | 133 | ||
| 134 | val eventCollector = EventCollector(room.events, coroutineRule.scope) | 134 | val eventCollector = EventCollector(room.events, coroutineRule.scope) |
| @@ -138,6 +138,32 @@ class RoomTest { | @@ -138,6 +138,32 @@ class RoomTest { | ||
| 138 | assertEquals(1, events.size) | 138 | assertEquals(1, events.size) |
| 139 | assertEquals(true, events[0] is RoomEvent.Disconnected) | 139 | assertEquals(true, events[0] is RoomEvent.Disconnected) |
| 140 | assertEquals(DisconnectReason.SERVER_SHUTDOWN, (events[0] as RoomEvent.Disconnected).reason) | 140 | assertEquals(DisconnectReason.SERVER_SHUTDOWN, (events[0] as RoomEvent.Disconnected).reason) |
| 141 | + | ||
| 142 | + // Verify Room state | ||
| 143 | + assertEquals(Room.State.DISCONNECTED, room.state) | ||
| 144 | + assertNull(room.sid) | ||
| 145 | + assertNull(room.metadata) | ||
| 146 | + assertNull(room.name) | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + @Test | ||
| 150 | + fun onDisconnect() = runTest { | ||
| 151 | + | ||
| 152 | + connect() | ||
| 153 | + val eventCollector = EventCollector(room.events, coroutineRule.scope) | ||
| 154 | + room.disconnect() | ||
| 155 | + val events = eventCollector.stopCollecting() | ||
| 156 | + | ||
| 157 | + assertEquals(1, events.size) | ||
| 158 | + assertEquals(true, events[0] is RoomEvent.Disconnected) | ||
| 159 | + assertEquals(DisconnectReason.CLIENT_INITIATED, (events[0] as RoomEvent.Disconnected).reason) | ||
| 160 | + | ||
| 161 | + // Verify Room state | ||
| 162 | + assertEquals(Room.State.DISCONNECTED, room.state) | ||
| 163 | + assertNull(room.sid) | ||
| 164 | + assertNull(room.metadata) | ||
| 165 | + assertNull(room.name) | ||
| 166 | + | ||
| 141 | } | 167 | } |
| 142 | 168 | ||
| 143 | @Test | 169 | @Test |
livekit-android-sdk/src/test/java/io/livekit/android/room/participant/LocalParticipantMockE2ETest.kt
0 → 100644
| 1 | +package io.livekit.android.room.participant | ||
| 2 | + | ||
| 3 | +import io.livekit.android.MockE2ETest | ||
| 4 | +import io.livekit.android.mock.MockAudioStreamTrack | ||
| 5 | +import io.livekit.android.room.SignalClientTest | ||
| 6 | +import io.livekit.android.room.track.LocalAudioTrack | ||
| 7 | +import io.livekit.android.util.toOkioByteString | ||
| 8 | +import kotlinx.coroutines.ExperimentalCoroutinesApi | ||
| 9 | +import kotlinx.coroutines.launch | ||
| 10 | +import kotlinx.coroutines.test.advanceUntilIdle | ||
| 11 | +import kotlinx.coroutines.test.runCurrent | ||
| 12 | +import org.junit.Assert.* | ||
| 13 | +import org.junit.Test | ||
| 14 | +import org.junit.runner.RunWith | ||
| 15 | +import org.robolectric.RobolectricTestRunner | ||
| 16 | + | ||
| 17 | +@ExperimentalCoroutinesApi | ||
| 18 | +@RunWith(RobolectricTestRunner::class) | ||
| 19 | +class LocalParticipantMockE2ETest : MockE2ETest() { | ||
| 20 | + | ||
| 21 | + @Test | ||
| 22 | + fun disconnectCleansLocalParticipant() = runTest { | ||
| 23 | + | ||
| 24 | + connect() | ||
| 25 | + | ||
| 26 | + val publishJob = launch { | ||
| 27 | + room.localParticipant.publishAudioTrack( | ||
| 28 | + LocalAudioTrack( | ||
| 29 | + "", | ||
| 30 | + MockAudioStreamTrack(id = SignalClientTest.LOCAL_TRACK_PUBLISHED.trackPublished.cid) | ||
| 31 | + ) | ||
| 32 | + ) | ||
| 33 | + } | ||
| 34 | + wsFactory.listener.onMessage(wsFactory.ws, SignalClientTest.LOCAL_TRACK_PUBLISHED.toOkioByteString()) | ||
| 35 | + publishJob.join() | ||
| 36 | + | ||
| 37 | + room.disconnect() | ||
| 38 | + | ||
| 39 | + assertEquals("", room.localParticipant.sid) | ||
| 40 | + assertNull(room.localParticipant.name) | ||
| 41 | + assertNull(room.localParticipant.identity) | ||
| 42 | + assertNull(room.localParticipant.metadata) | ||
| 43 | + assertNull(room.localParticipant.permissions) | ||
| 44 | + assertNull(room.localParticipant.participantInfo) | ||
| 45 | + assertFalse(room.localParticipant.isSpeaking) | ||
| 46 | + assertEquals(ConnectionQuality.UNKNOWN, room.localParticipant.connectionQuality) | ||
| 47 | + | ||
| 48 | + assertEquals(0, room.localParticipant.tracks.values.size) | ||
| 49 | + assertEquals(0, room.localParticipant.audioTracks.size) | ||
| 50 | + assertEquals(0, room.localParticipant.videoTracks.size) | ||
| 51 | + } | ||
| 52 | +} |
| @@ -7,6 +7,7 @@ import io.livekit.android.room.track.TrackPublication | @@ -7,6 +7,7 @@ import io.livekit.android.room.track.TrackPublication | ||
| 7 | import kotlinx.coroutines.ExperimentalCoroutinesApi | 7 | import kotlinx.coroutines.ExperimentalCoroutinesApi |
| 8 | import kotlinx.coroutines.test.runTest | 8 | import kotlinx.coroutines.test.runTest |
| 9 | import livekit.LivekitModels | 9 | import livekit.LivekitModels |
| 10 | +import org.junit.Assert | ||
| 10 | import org.junit.Assert.assertEquals | 11 | import org.junit.Assert.assertEquals |
| 11 | import org.junit.Assert.assertTrue | 12 | import org.junit.Assert.assertTrue |
| 12 | import org.junit.Before | 13 | import org.junit.Before |
| @@ -117,6 +118,22 @@ class ParticipantTest { | @@ -117,6 +118,22 @@ class ParticipantTest { | ||
| 117 | assertEquals(audioPublication, participant.audioTracks.first().first) | 118 | assertEquals(audioPublication, participant.audioTracks.first().first) |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 121 | + @Test | ||
| 122 | + fun dispose() = runTest { | ||
| 123 | + val audioPublication = TrackPublication(TRACK_INFO, null, participant) | ||
| 124 | + participant.addTrackPublication(audioPublication) | ||
| 125 | + | ||
| 126 | + participant.dispose() | ||
| 127 | + assertEquals("", participant.sid) | ||
| 128 | + Assert.assertNull(participant.name) | ||
| 129 | + Assert.assertNull(participant.identity) | ||
| 130 | + Assert.assertNull(participant.metadata) | ||
| 131 | + Assert.assertNull(participant.permissions) | ||
| 132 | + Assert.assertNull(participant.participantInfo) | ||
| 133 | + Assert.assertFalse(participant.isSpeaking) | ||
| 134 | + assertEquals(ConnectionQuality.UNKNOWN, participant.connectionQuality) | ||
| 135 | + } | ||
| 136 | + | ||
| 120 | companion object { | 137 | companion object { |
| 121 | val INFO = LivekitModels.ParticipantInfo.newBuilder() | 138 | val INFO = LivekitModels.ParticipantInfo.newBuilder() |
| 122 | .setSid("sid") | 139 | .setSid("sid") |
-
请 注册 或 登录 后发表评论