Fix: re-publish tracks after re connect (#238)
* fix republish local tracks after reconnect. * update flutter-webrtc. * remove unused import. * add dart_webrtc. * cleanup. * fix: Fix sendSyncState timing error, when reconnecting is sending. * Adjust the re-connect logic to ensure that the publisher negotiates and reconnects correctly. * Update room.dart
This commit is contained in:
@@ -60,6 +60,8 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
// 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<EngineEvent> {
|
||||
].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<EngineEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
@internal
|
||||
Future<void> resumeConnection() async {
|
||||
if (_connectionState == ConnectionState.disconnected) {
|
||||
logger.fine('resumeConnection: Already closed.');
|
||||
@@ -633,10 +637,15 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
@internal
|
||||
Future<void> 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<EngineEvent> {
|
||||
_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<EngineEvent> {
|
||||
fastConnectOptions: fastConnectOptions,
|
||||
);
|
||||
|
||||
if (_hasPublished) {
|
||||
await negotiate();
|
||||
logger.fine('restartConnection: Waiting for publisher to ice-connect...');
|
||||
await events.waitFor<EnginePublisherPeerStateUpdatedEvent>(
|
||||
filter: (event) => event.state.isConnected(),
|
||||
duration: connectOptions.timeouts.peerConnection,
|
||||
);
|
||||
}
|
||||
|
||||
fullReconnect = false;
|
||||
_restarting = false;
|
||||
}
|
||||
|
||||
@internal
|
||||
@@ -767,6 +787,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
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) {
|
||||
|
||||
+3
-11
@@ -166,7 +166,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
||||
}
|
||||
|
||||
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<RoomEvent> {
|
||||
})
|
||||
..on<SignalConnectionStateUpdatedEvent>((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<RoomEvent> {
|
||||
} 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<RoomEvent> {
|
||||
await _cleanUp();
|
||||
}
|
||||
|
||||
Future<void> reconnect() async {
|
||||
await engine.restartConnection();
|
||||
}
|
||||
|
||||
RemoteParticipant _getOrCreateRemoteParticipant(
|
||||
String sid, lk_models.ParticipantInfo? info) {
|
||||
RemoteParticipant? participant = _participants[sid];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -124,6 +124,7 @@ extension LocalVideoTrackExt on LocalVideoTrack {
|
||||
}
|
||||
|
||||
if (fastSwitch) {
|
||||
currentOptions = options.copyWith(deviceId: deviceId);
|
||||
await rtc.Helper.switchCamera(mediaStreamTrack, deviceId, mediaStream);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user