diff --git a/.changes/add-reconnect-reason b/.changes/add-reconnect-reason new file mode 100644 index 000000000..ae3e46a3f --- /dev/null +++ b/.changes/add-reconnect-reason @@ -0,0 +1 @@ +patch type="added" "Send reconnect reason to server during WebSocket reconnection" diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index 2bcb9a128..a88cff287 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -327,7 +327,10 @@ class Engine extends Disposable with EventsEmittable { if (error is NegotiationError) { fullReconnectOnNext = true; } - await handleReconnect(ClientDisconnectReason.negotiationFailed); + await handleReconnect( + ClientDisconnectReason.negotiationFailed, + reconnectReason: lk_models.ReconnectReason.RR_UNKNOWN, + ); } } @@ -669,9 +672,10 @@ class Engine extends Disposable with EventsEmittable { )); logger.fine('subscriber connectionState: $state'); if (state.isDisconnected() || state.isFailed()) { - await handleReconnect(state.isFailed() - ? ClientDisconnectReason.peerConnectionFailed - : ClientDisconnectReason.peerConnectionClosed); + await handleReconnect( + state.isFailed() ? ClientDisconnectReason.peerConnectionFailed : ClientDisconnectReason.peerConnectionClosed, + reconnectReason: lk_models.ReconnectReason.RR_SUBSCRIBER_FAILED, + ); } }; @@ -689,9 +693,10 @@ class Engine extends Disposable with EventsEmittable { )); logger.fine('publisher connectionState: $state'); if (state.isDisconnected() || state.isFailed()) { - await handleReconnect(state.isFailed() - ? ClientDisconnectReason.peerConnectionFailed - : ClientDisconnectReason.peerConnectionClosed); + await handleReconnect( + state.isFailed() ? ClientDisconnectReason.peerConnectionFailed : ClientDisconnectReason.peerConnectionClosed, + reconnectReason: lk_models.ReconnectReason.RR_PUBLISHER_FAILED, + ); } }; @@ -980,7 +985,10 @@ class Engine extends Disposable with EventsEmittable { } @internal - Future handleReconnect(ClientDisconnectReason reason) async { + Future handleReconnect( + ClientDisconnectReason reason, { + lk_models.ReconnectReason? reconnectReason, + }) async { if (_isClosed) { logger.fine('handleReconnect: engine is closed, skip'); return; @@ -1021,12 +1029,18 @@ class Engine extends Disposable with EventsEmittable { } logger.fine('WebSocket reconnecting in $delay ms, retry times $reconnectAttempts'); reconnectTimeout = Timer(Duration(milliseconds: delay), () async { - await attemptReconnect(reason); + await attemptReconnect( + reason, + reconnectReason: reconnectReason, + ); }); } @internal - Future attemptReconnect(ClientDisconnectReason reason) async { + Future attemptReconnect( + ClientDisconnectReason reason, { + lk_models.ReconnectReason? reconnectReason, + }) async { if (_isClosed) { return; } @@ -1062,7 +1076,10 @@ class Engine extends Disposable with EventsEmittable { if (fullReconnectOnNext) { await restartConnection(); } else { - await resumeConnection(reason); + await resumeConnection( + reason, + reconnectReason: reconnectReason, + ); } clearPendingReconnect(); attemptingReconnect = false; @@ -1093,7 +1110,10 @@ class Engine extends Disposable with EventsEmittable { } } - Future resumeConnection(ClientDisconnectReason reason) async { + Future resumeConnection( + ClientDisconnectReason reason, { + lk_models.ReconnectReason? reconnectReason, + }) async { if (_isClosed) { return; } @@ -1107,6 +1127,7 @@ class Engine extends Disposable with EventsEmittable { connectOptions: connectOptions, roomOptions: roomOptions, reconnect: true, + reconnectReason: reconnectReason, ); await events.waitFor( @@ -1322,7 +1343,8 @@ class Engine extends Disposable with EventsEmittable { ..on((event) async { logger.fine('Signal disconnected ${event.reason}'); if (event.reason == DisconnectReason.disconnected && !_isClosed) { - await handleReconnect(ClientDisconnectReason.signal); + await handleReconnect(ClientDisconnectReason.signal, + reconnectReason: lk_models.ReconnectReason.RR_SIGNAL_DISCONNECTED); } else if (event.reason == DisconnectReason.signalingConnectionFailure) { events.emit(EngineDisconnectedEvent( reason: event.reason, diff --git a/lib/src/core/signal_client.dart b/lib/src/core/signal_client.dart index 91311e327..89bdb258f 100644 --- a/lib/src/core/signal_client.dart +++ b/lib/src/core/signal_client.dart @@ -101,6 +101,7 @@ class SignalClient extends Disposable with EventsEmittable { required ConnectOptions connectOptions, required RoomOptions roomOptions, bool reconnect = false, + lk_models.ReconnectReason? reconnectReason, }) async { if (!kIsWeb && !lkPlatformIsTest()) { _connectivityResult = await Connectivity().checkConnectivity(); @@ -133,6 +134,7 @@ class SignalClient extends Disposable with EventsEmittable { roomOptions: roomOptions, reconnect: reconnect, sid: reconnect ? participantSid : null, + reconnectReason: reconnectReason, ); logger.fine('SignalClient connecting with url: $rtcUri'); diff --git a/lib/src/utils.dart b/lib/src/utils.dart index aa8259ea3..cb0297d05 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -166,6 +166,7 @@ class Utils { bool validate = false, bool forceSecure = false, String? sid, + lk_models.ReconnectReason? reconnectReason, }) async { final Uri uri = Uri.parse(uriString); @@ -191,6 +192,7 @@ class Utils { 'auto_subscribe': connectOptions.autoSubscribe ? '1' : '0', 'adaptive_stream': roomOptions.adaptiveStream ? '1' : '0', if (reconnect) 'reconnect': '1', + if (reconnect && reconnectReason != null) 'reconnect_reason': reconnectReason.value.toString(), if (reconnect && sid != null) 'sid': sid, 'protocol': connectOptions.protocolVersion.toStringValue(), 'sdk': 'flutter',