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:
@@ -216,18 +216,6 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
if (result == true) await widget.room.disconnect();
|
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 {
|
void _onTapUpdateSubscribePermission() async {
|
||||||
final result = await context.showSubscribePermissionDialog();
|
final result = await context.showSubscribePermissionDialog();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@@ -440,11 +428,6 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
icon: const Icon(EvaIcons.paperPlane),
|
icon: const Icon(EvaIcons.paperPlane),
|
||||||
tooltip: 'send demo data',
|
tooltip: 'send demo data',
|
||||||
),
|
),
|
||||||
IconButton(
|
|
||||||
onPressed: _onTapReconnect,
|
|
||||||
icon: const Icon(EvaIcons.refresh),
|
|
||||||
tooltip: 're-connect',
|
|
||||||
),
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: _onTapUpdateSubscribePermission,
|
onPressed: _onTapUpdateSubscribePermission,
|
||||||
icon: const Icon(EvaIcons.settings2),
|
icon: const Icon(EvaIcons.settings2),
|
||||||
|
|||||||
@@ -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
|
// this is helpful to know if we need to restart ICE on the publisher connection
|
||||||
bool _hasPublished = false;
|
bool _hasPublished = false;
|
||||||
|
|
||||||
|
bool _restarting = false;
|
||||||
|
|
||||||
lk_models.ClientConfiguration? _clientConfiguration;
|
lk_models.ClientConfiguration? _clientConfiguration;
|
||||||
|
|
||||||
// remember url and token for reconnect
|
// remember url and token for reconnect
|
||||||
@@ -548,7 +550,8 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
].contains(reason);
|
].contains(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_connectionState == ConnectionState.reconnecting && !fullReconnect) {
|
if (_restarting ||
|
||||||
|
(_connectionState == ConnectionState.reconnecting && !fullReconnect)) {
|
||||||
logger.fine('[$objectId] Already reconnecting...');
|
logger.fine('[$objectId] Already reconnecting...');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -566,6 +569,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@internal
|
||||||
Future<void> resumeConnection() async {
|
Future<void> resumeConnection() async {
|
||||||
if (_connectionState == ConnectionState.disconnected) {
|
if (_connectionState == ConnectionState.disconnected) {
|
||||||
logger.fine('resumeConnection: Already closed.');
|
logger.fine('resumeConnection: Already closed.');
|
||||||
@@ -633,10 +637,15 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@internal
|
||||||
Future<void> restartConnection([bool signalEvents = false]) async {
|
Future<void> restartConnection([bool signalEvents = false]) async {
|
||||||
|
if (_restarting) {
|
||||||
|
logger.fine('restartConnection: Already restarting...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_restarting = true;
|
||||||
await publisher?.dispose();
|
await publisher?.dispose();
|
||||||
publisher = null;
|
publisher = null;
|
||||||
_hasPublished = false;
|
|
||||||
|
|
||||||
await subscriber?.dispose();
|
await subscriber?.dispose();
|
||||||
subscriber = null;
|
subscriber = null;
|
||||||
@@ -646,6 +655,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
_lossyDCSub = null;
|
_lossyDCSub = null;
|
||||||
_lossyDCPub = null;
|
_lossyDCPub = null;
|
||||||
await _signalListener.cancelAll();
|
await _signalListener.cancelAll();
|
||||||
|
await events.cancelAll();
|
||||||
_signalListener = signalClient.createListener(synchronized: true);
|
_signalListener = signalClient.createListener(synchronized: true);
|
||||||
_setUpSignalListeners();
|
_setUpSignalListeners();
|
||||||
|
|
||||||
@@ -657,7 +667,17 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
fastConnectOptions: fastConnectOptions,
|
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;
|
fullReconnect = false;
|
||||||
|
_restarting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@internal
|
@internal
|
||||||
@@ -767,6 +787,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
|||||||
fullReconnect = true;
|
fullReconnect = true;
|
||||||
// reconnect immediately instead of waiting for next attempt
|
// reconnect immediately instead of waiting for next attempt
|
||||||
_connectionState = ConnectionState.reconnecting;
|
_connectionState = ConnectionState.reconnecting;
|
||||||
|
_updateConnectionState(ConnectionState.reconnecting);
|
||||||
await handleDisconnect(DisconnectReason.leaveReconnect);
|
await handleDisconnect(DisconnectReason.leaveReconnect);
|
||||||
} else {
|
} else {
|
||||||
if (_connectionState == ConnectionState.reconnecting) {
|
if (_connectionState == ConnectionState.reconnecting) {
|
||||||
|
|||||||
+3
-11
@@ -166,7 +166,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (connectOptions.protocolVersion.index >= ProtocolVersion.v8.index &&
|
if (connectOptions.protocolVersion.index >= ProtocolVersion.v8.index &&
|
||||||
engine.fastConnectOptions != null) {
|
engine.fastConnectOptions != null &&
|
||||||
|
!engine.fullReconnect) {
|
||||||
var options = engine.fastConnectOptions!;
|
var options = engine.fastConnectOptions!;
|
||||||
|
|
||||||
var audio = options.microphone;
|
var audio = options.microphone;
|
||||||
@@ -263,7 +264,7 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
|||||||
})
|
})
|
||||||
..on<SignalConnectionStateUpdatedEvent>((event) {
|
..on<SignalConnectionStateUpdatedEvent>((event) {
|
||||||
// during reconnection, need to send sync state upon signal connection.
|
// during reconnection, need to send sync state upon signal connection.
|
||||||
if (event.didReconnect) {
|
if (event.newState == ConnectionState.reconnecting) {
|
||||||
logger.fine('Sending syncState');
|
logger.fine('Sending syncState');
|
||||||
_sendSyncState();
|
_sendSyncState();
|
||||||
}
|
}
|
||||||
@@ -306,11 +307,6 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
|||||||
} else if (event.fullReconnect &&
|
} else if (event.fullReconnect &&
|
||||||
event.newState == ConnectionState.connected) {
|
event.newState == ConnectionState.connected) {
|
||||||
events.emit(const RoomRestartedEvent());
|
events.emit(const RoomRestartedEvent());
|
||||||
// recreate signal listener.
|
|
||||||
await _signalListener.cancelAll();
|
|
||||||
await _signalListener.dispose();
|
|
||||||
_signalListener = engine.signalClient.createListener();
|
|
||||||
_setUpSignalListeners();
|
|
||||||
await _handlePostReconnect(event.fullReconnect);
|
await _handlePostReconnect(event.fullReconnect);
|
||||||
} else if (event.newState == ConnectionState.reconnecting) {
|
} else if (event.newState == ConnectionState.reconnecting) {
|
||||||
events.emit(const RoomReconnectingEvent());
|
events.emit(const RoomReconnectingEvent());
|
||||||
@@ -366,10 +362,6 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
|
|||||||
await _cleanUp();
|
await _cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> reconnect() async {
|
|
||||||
await engine.restartConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteParticipant _getOrCreateRemoteParticipant(
|
RemoteParticipant _getOrCreateRemoteParticipant(
|
||||||
String sid, lk_models.ParticipantInfo? info) {
|
String sid, lk_models.ParticipantInfo? info) {
|
||||||
RemoteParticipant? participant = _participants[sid];
|
RemoteParticipant? participant = _participants[sid];
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ class Transport extends Disposable {
|
|||||||
pc.onRenegotiationNeeded = null;
|
pc.onRenegotiationNeeded = null;
|
||||||
pc.onIceCandidate = null;
|
pc.onIceCandidate = null;
|
||||||
pc.onConnectionState = null;
|
pc.onConnectionState = null;
|
||||||
|
pc.onIceConnectionState = null;
|
||||||
pc.onTrack = null;
|
pc.onTrack = null;
|
||||||
|
|
||||||
// Remove all senders
|
// Remove all senders
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ extension LocalVideoTrackExt on LocalVideoTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fastSwitch) {
|
if (fastSwitch) {
|
||||||
|
currentOptions = options.copyWith(deviceId: deviceId);
|
||||||
await rtc.Helper.switchCamera(mediaStreamTrack, deviceId, mediaStream);
|
await rtc.Helper.switchCamera(mediaStreamTrack, deviceId, mediaStream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,9 +25,9 @@ dependencies:
|
|||||||
protobuf: ^2.1.0
|
protobuf: ^2.1.0
|
||||||
flutter_webrtc: 0.9.22
|
flutter_webrtc: 0.9.22
|
||||||
flutter_window_close: ^0.2.2
|
flutter_window_close: ^0.2.2
|
||||||
dart_webrtc: 1.0.15
|
|
||||||
device_info_plus: ^8.0.0
|
device_info_plus: ^8.0.0
|
||||||
webrtc_interface: 1.0.11
|
webrtc_interface: 1.0.11
|
||||||
|
dart_webrtc: 1.0.15
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user