From abd6bb32b693aa453e23bae750e44bf3a8ea212a Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Mon, 27 Mar 2023 09:20:18 +0800 Subject: [PATCH] feat: handle reconnect response to re-configuration PCs. (#255) * feat: handle reconnect response to re-configuration PCs. * chore: fn rename. * fmt: format proto/*.dart. * update. --- lib/src/core/engine.dart | 43 +++++++++++++++++++++++++++------ lib/src/core/signal_client.dart | 3 +++ lib/src/internal/events.dart | 9 +++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 080dfb1..367e943 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -278,14 +278,9 @@ class Engine extends Disposable with EventsEmittable { await channel.send(message); } - Future _configurePeerConnections( + Future _buildRtcConfiguration( {required lk_models.ClientConfigSetting serverResponseForceRelay, required List serverProvidedIceServers}) async { - if (publisher != null || subscriber != null) { - logger.warning('Already configured'); - return; - } - // RTCConfiguration? config; RTCConfiguration rtcConfiguration = connectOptions.rtcConfiguration; @@ -304,6 +299,10 @@ class Engine extends Disposable with EventsEmittable { ); } + return rtcConfiguration; + } + + Future _createPeerConnections(RTCConfiguration rtcConfiguration) async { publisher = await Transport.create(_peerConnectionCreate, rtcConfig: rtcConfiguration, connectOptions: connectOptions); subscriber = await Transport.create(_peerConnectionCreate, @@ -710,16 +709,46 @@ class Engine extends Disposable with EventsEmittable { 'iceServers: ${event.response.iceServers}, ' 'forceRelay: $event.response.clientConfiguration.forceRelay'); - await _configurePeerConnections( + var rtcConfiguration = await _buildRtcConfiguration( serverResponseForceRelay: event.response.clientConfiguration.forceRelay, serverProvidedIceServers: _serverProvidedIceServers); + if (publisher == null && subscriber == null) { + await _createPeerConnections(rtcConfiguration); + } + if (!_subscriberPrimary) { // for subscriberPrimary, we negotiate when necessary (lazy) await negotiate(); } }) + ..on((event) async { + var iceServersFromServer = + event.response.iceServers.map((e) => e.toSDKType()).toList(); + + if (iceServersFromServer.isNotEmpty) { + _serverProvidedIceServers = iceServersFromServer; + } + + _clientConfiguration = event.response.clientConfiguration; + + logger.fine('Handle ReconnectResponse: ' + 'iceServers: ${event.response.iceServers}, ' + 'forceRelay: $event.response.clientConfiguration.forceRelay'); + + var rtcConfiguration = await _buildRtcConfiguration( + serverResponseForceRelay: + event.response.clientConfiguration.forceRelay, + serverProvidedIceServers: _serverProvidedIceServers); + + await publisher?.pc.setConfiguration(rtcConfiguration.toMap()); + await subscriber?.pc.setConfiguration(rtcConfiguration.toMap()); + + if (!_subscriberPrimary) { + await negotiate(); + } + }) ..on((event) async { if (event.newState == ConnectionState.disconnected) { await handleDisconnect(ClientDisconnectReason.signal); diff --git a/lib/src/core/signal_client.dart b/lib/src/core/signal_client.dart index 692e957..c09c2cc 100644 --- a/lib/src/core/signal_client.dart +++ b/lib/src/core/signal_client.dart @@ -247,6 +247,9 @@ class SignalClient extends Disposable with EventsEmittable { _pingCount++; _resetPingTimeout(); break; + case lk_rtc.SignalResponse_Message.reconnect: + events.emit(SignalReconnectResponseEvent(response: msg.reconnect)); + break; default: logger.warning('received unknown signal message'); } diff --git a/lib/src/internal/events.dart b/lib/src/internal/events.dart index b64b4e5..042849e 100644 --- a/lib/src/internal/events.dart +++ b/lib/src/internal/events.dart @@ -101,6 +101,15 @@ class SignalJoinResponseEvent with SignalEvent, InternalEvent { }); } +@internal +// Received a ReconnectResponse from the server. +class SignalReconnectResponseEvent with SignalEvent, InternalEvent { + final lk_rtc.ReconnectResponse response; + const SignalReconnectResponseEvent({ + required this.response, + }); +} + /// Base class for a ConnectionStateUpdated event @internal abstract class ConnectionStateUpdatedEvent with InternalEvent {