diff --git a/.changes/protocol-v13 b/.changes/protocol-v13 new file mode 100644 index 00000000..3f973f1d --- /dev/null +++ b/.changes/protocol-v13 @@ -0,0 +1 @@ +minor type="feature" "Support protocol v13 with LeaveRequest action" diff --git a/lib/src/core/engine.dart b/lib/src/core/engine.dart index e667659d..570e3101 100644 --- a/lib/src/core/engine.dart +++ b/lib/src/core/engine.dart @@ -1351,31 +1351,32 @@ class Engine extends Disposable with EventsEmittable { token = event.token; }) ..on((event) async { + logger.fine('[Signal] Leave received, action: ${event.action}, reason: ${event.reason}'); if (event.regions != null && _regionUrlProvider != null) { logger.fine('updating regions'); _regionUrlProvider?.setServerReportedRegions(event.regions!); } - switch (event.action) { - case lk_rtc.LeaveRequest_Action.DISCONNECT: - if (connectionState == ConnectionState.reconnecting) { - logger.warning('[Signal] Received Leave while engine is reconnecting, ignoring...'); - return; - } - await signalClient.cleanUp(); - fullReconnectOnNext = false; - await disconnect(); - events.emit(EngineDisconnectedEvent(reason: event.reason.toSDKType())); - break; - case lk_rtc.LeaveRequest_Action.RECONNECT: - fullReconnectOnNext = true; - // reconnect immediately instead of waiting for next attempt - await handleReconnect(ClientDisconnectReason.leaveReconnect); - break; - case lk_rtc.LeaveRequest_Action.RESUME: - // reconnect immediately instead of waiting for next attempt - await handleReconnect(ClientDisconnectReason.leaveReconnect); - default: - break; + // Protocol v13: LeaveRequest.action replaces the deprecated canReconnect boolean. + // canReconnect is still checked for backward compatibility with v12 servers + // (where action defaults to DISCONNECT=0 since it's unset). + if (event.action == lk_rtc.LeaveRequest_Action.RESUME) { + fullReconnectOnNext = false; + // reconnect immediately instead of waiting for next attempt + await handleReconnect(ClientDisconnectReason.leaveReconnect); + } else if (event.action == lk_rtc.LeaveRequest_Action.RECONNECT || event.canReconnect) { + fullReconnectOnNext = true; + // reconnect immediately instead of waiting for next attempt + await handleReconnect(ClientDisconnectReason.leaveReconnect); + } else { + // DISCONNECT or v12 server with canReconnect=false + if (connectionState == ConnectionState.reconnecting) { + logger.warning('[Signal] Received Leave while engine is reconnecting, ignoring...'); + return; + } + await signalClient.cleanUp(); + fullReconnectOnNext = false; + await disconnect(); + events.emit(EngineDisconnectedEvent(reason: event.reason.toSDKType())); } }); diff --git a/lib/src/core/signal_client.dart b/lib/src/core/signal_client.dart index 47ce0883..388b4096 100644 --- a/lib/src/core/signal_client.dart +++ b/lib/src/core/signal_client.dart @@ -199,7 +199,11 @@ class SignalClient extends Disposable with EventsEmittable { Future sendLeave() async { _sendRequest(lk_rtc.SignalRequest( - leave: lk_rtc.LeaveRequest(canReconnect: false, reason: lk_models.DisconnectReason.CLIENT_INITIATED))); + leave: lk_rtc.LeaveRequest( + reason: lk_models.DisconnectReason.CLIENT_INITIATED, + // server doesn't process this field, keeping it here to indicate the intent of a full disconnect + action: lk_rtc.LeaveRequest_Action.DISCONNECT, + ))); } // resets internal state to a re-usable state diff --git a/lib/src/extensions.dart b/lib/src/extensions.dart index d919da94..a5d43d7f 100644 --- a/lib/src/extensions.dart +++ b/lib/src/extensions.dart @@ -66,6 +66,7 @@ extension ProtocolVersionExt on ProtocolVersion { ProtocolVersion.v10: '10', ProtocolVersion.v11: '11', ProtocolVersion.v12: '12', + ProtocolVersion.v13: '13', }[this]!; } diff --git a/lib/src/options.dart b/lib/src/options.dart index af31ce5f..a18f53a6 100644 --- a/lib/src/options.dart +++ b/lib/src/options.dart @@ -64,7 +64,7 @@ class ConnectOptions { const ConnectOptions({ this.autoSubscribe = true, this.rtcConfiguration = const RTCConfiguration(), - this.protocolVersion = ProtocolVersion.v12, + this.protocolVersion = ProtocolVersion.v13, this.timeouts = Timeouts.defaultTimeouts, }); } diff --git a/lib/src/types/other.dart b/lib/src/types/other.dart index 46f39b07..35e1cd13 100644 --- a/lib/src/types/other.dart +++ b/lib/src/types/other.dart @@ -35,6 +35,7 @@ enum ProtocolVersion { v10, v11, v12, + v13, // Regions in leave request, canReconnect obsoleted by action } /// Connection state type used throughout the SDK.