diff --git a/example/lib/widgets/controls.dart b/example/lib/widgets/controls.dart index 42fbc4f..5c2256c 100644 --- a/example/lib/widgets/controls.dart +++ b/example/lib/widgets/controls.dart @@ -216,18 +216,6 @@ class _ControlsWidgetState extends State { if (result == true) await widget.room.disconnect(); } - void _onTapReconnect() async { - final result = await context.showReconnectDialog(); - if (result == true) { - try { - await widget.room.reconnect(); - await context.showReconnectSuccessDialog(); - } catch (error) { - await context.showErrorDialog(error); - } - } - } - void _onTapUpdateSubscribePermission() async { final result = await context.showSubscribePermissionDialog(); if (result != null) { @@ -440,11 +428,6 @@ class _ControlsWidgetState extends State { icon: const Icon(EvaIcons.paperPlane), tooltip: 'send demo data', ), - IconButton( - onPressed: _onTapReconnect, - icon: const Icon(EvaIcons.refresh), - tooltip: 're-connect', - ), IconButton( onPressed: _onTapUpdateSubscribePermission, icon: const Icon(EvaIcons.settings2), diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 6a633cd..5290885 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -60,6 +60,8 @@ class Engine extends Disposable with EventsEmittable { // this is helpful to know if we need to restart ICE on the publisher connection bool _hasPublished = false; + bool _restarting = false; + lk_models.ClientConfiguration? _clientConfiguration; // remember url and token for reconnect @@ -548,7 +550,8 @@ class Engine extends Disposable with EventsEmittable { ].contains(reason); } - if (_connectionState == ConnectionState.reconnecting && !fullReconnect) { + if (_restarting || + (_connectionState == ConnectionState.reconnecting && !fullReconnect)) { logger.fine('[$objectId] Already reconnecting...'); return; } @@ -566,6 +569,7 @@ class Engine extends Disposable with EventsEmittable { } } + @internal Future resumeConnection() async { if (_connectionState == ConnectionState.disconnected) { logger.fine('resumeConnection: Already closed.'); @@ -633,10 +637,15 @@ class Engine extends Disposable with EventsEmittable { } } + @internal Future restartConnection([bool signalEvents = false]) async { + if (_restarting) { + logger.fine('restartConnection: Already restarting...'); + return; + } + _restarting = true; await publisher?.dispose(); publisher = null; - _hasPublished = false; await subscriber?.dispose(); subscriber = null; @@ -646,6 +655,7 @@ class Engine extends Disposable with EventsEmittable { _lossyDCSub = null; _lossyDCPub = null; await _signalListener.cancelAll(); + await events.cancelAll(); _signalListener = signalClient.createListener(synchronized: true); _setUpSignalListeners(); @@ -657,7 +667,17 @@ class Engine extends Disposable with EventsEmittable { fastConnectOptions: fastConnectOptions, ); + if (_hasPublished) { + await negotiate(); + logger.fine('restartConnection: Waiting for publisher to ice-connect...'); + await events.waitFor( + filter: (event) => event.state.isConnected(), + duration: connectOptions.timeouts.peerConnection, + ); + } + fullReconnect = false; + _restarting = false; } @internal @@ -767,6 +787,7 @@ class Engine extends Disposable with EventsEmittable { fullReconnect = true; // reconnect immediately instead of waiting for next attempt _connectionState = ConnectionState.reconnecting; + _updateConnectionState(ConnectionState.reconnecting); await handleDisconnect(DisconnectReason.leaveReconnect); } else { if (_connectionState == ConnectionState.reconnecting) { diff --git a/lib/src/core/room.dart b/lib/src/core/room.dart index 81c37d8..485804b 100644 --- a/lib/src/core/room.dart +++ b/lib/src/core/room.dart @@ -166,7 +166,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable { } if (connectOptions.protocolVersion.index >= ProtocolVersion.v8.index && - engine.fastConnectOptions != null) { + engine.fastConnectOptions != null && + !engine.fullReconnect) { var options = engine.fastConnectOptions!; var audio = options.microphone; @@ -263,7 +264,7 @@ class Room extends DisposableChangeNotifier with EventsEmittable { }) ..on((event) { // during reconnection, need to send sync state upon signal connection. - if (event.didReconnect) { + if (event.newState == ConnectionState.reconnecting) { logger.fine('Sending syncState'); _sendSyncState(); } @@ -306,11 +307,6 @@ class Room extends DisposableChangeNotifier with EventsEmittable { } else if (event.fullReconnect && event.newState == ConnectionState.connected) { events.emit(const RoomRestartedEvent()); - // recreate signal listener. - await _signalListener.cancelAll(); - await _signalListener.dispose(); - _signalListener = engine.signalClient.createListener(); - _setUpSignalListeners(); await _handlePostReconnect(event.fullReconnect); } else if (event.newState == ConnectionState.reconnecting) { events.emit(const RoomReconnectingEvent()); @@ -366,10 +362,6 @@ class Room extends DisposableChangeNotifier with EventsEmittable { await _cleanUp(); } - Future reconnect() async { - await engine.restartConnection(); - } - RemoteParticipant _getOrCreateRemoteParticipant( String sid, lk_models.ParticipantInfo? info) { RemoteParticipant? participant = _participants[sid]; diff --git a/lib/src/core/transport.dart b/lib/src/core/transport.dart index 9b9ff6c..cce4a6a 100644 --- a/lib/src/core/transport.dart +++ b/lib/src/core/transport.dart @@ -37,6 +37,7 @@ class Transport extends Disposable { pc.onRenegotiationNeeded = null; pc.onIceCandidate = null; pc.onConnectionState = null; + pc.onIceConnectionState = null; pc.onTrack = null; // Remove all senders diff --git a/lib/src/track/local/video.dart b/lib/src/track/local/video.dart index c4d200c..fb1b583 100644 --- a/lib/src/track/local/video.dart +++ b/lib/src/track/local/video.dart @@ -124,6 +124,7 @@ extension LocalVideoTrackExt on LocalVideoTrack { } if (fastSwitch) { + currentOptions = options.copyWith(deviceId: deviceId); await rtc.Helper.switchCamera(mediaStreamTrack, deviceId, mediaStream); return; } diff --git a/pubspec.yaml b/pubspec.yaml index a988b12..7439bb2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,9 +25,9 @@ dependencies: protobuf: ^2.1.0 flutter_webrtc: 0.9.22 flutter_window_close: ^0.2.2 - dart_webrtc: 1.0.15 device_info_plus: ^8.0.0 webrtc_interface: 1.0.11 + dart_webrtc: 1.0.15 dev_dependencies: flutter_test: