From e57ed15d074edc908fc7930c0dd88663714b560f Mon Sep 17 00:00:00 2001 From: Max Heimbrock <43608204+MaxHeimbrock@users.noreply.github.com> Date: Wed, 13 May 2026 11:40:53 +0200 Subject: [PATCH] Meet: disconnect on background, reconnect on resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On iOS, the OS suspends the process within seconds of the screen locking or the app being backgrounded. While suspended, the Rust SDK's reconnect loop (10 attempts × 5s) cannot actually run, exhausts its retries, and fires Disconnected with no path to recover when the app returns to the foreground. Android shows the same symptom under longer backgrounding via Doze. Disconnect the room cleanly when OnApplicationPause(true) fires, and rebuild the connection — auto-restoring camera and mic if they were enabled — when the app resumes. This avoids relying on the engine's auto-reconnect across a suspension window where it can't make progress. Co-Authored-By: Claude Opus 4.7 (1M context) --- Samples~/Meet/Assets/Runtime/MeetManager.cs | 53 +++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/Samples~/Meet/Assets/Runtime/MeetManager.cs b/Samples~/Meet/Assets/Runtime/MeetManager.cs index fed49205..9e133322 100644 --- a/Samples~/Meet/Assets/Runtime/MeetManager.cs +++ b/Samples~/Meet/Assets/Runtime/MeetManager.cs @@ -47,6 +47,12 @@ public class MeetManager : MonoBehaviour private bool _cameraActive; private bool _microphoneActive; + // State snapshot taken when the app is backgrounded, so we can restore + // the call on resume. See OnApplicationPause. + private bool _wasConnectedBeforePause; + private bool _wasCameraActiveBeforePause; + private bool _wasMicrophoneActiveBeforePause; + #region Lifecycle private void Start() @@ -64,12 +70,53 @@ private void Start() _placeholderTexture = Resources.Load(PlaceholderTextureResourceName); } + // On mobile, the OS suspends our process shortly after the screen locks or the app is + // backgrounded. While suspended, the Rust SDK's reconnect loop (10 attempts × 5s) burns + // through retries it can't actually run, and ends up firing Disconnected with no path to + // recover. To get predictable behavior we disconnect cleanly on pause and rebuild the + // connection on resume. private void OnApplicationPause(bool pause) { - if (_webCamTexture == null) return; + if (pause) HandlePause(); + else HandleResume(); + } + + private void HandlePause() + { + _webCamTexture?.Pause(); + + if (_room == null) return; + + Debug.Log("App backgrounded; disconnecting from room"); + _wasConnectedBeforePause = true; + _wasCameraActiveBeforePause = _cameraActive; + _wasMicrophoneActiveBeforePause = _microphoneActive; + + _room.Disconnect(); + CleanUpAllTracks(); + _room = null; + _localId = null; + buttonBar.SetConnected(false); + } + + private void HandleResume() + { + _webCamTexture?.Play(); + + if (!_wasConnectedBeforePause) return; + _wasConnectedBeforePause = false; + + Debug.Log("App resumed; reconnecting to room"); + StartCoroutine(ReconnectAfterResume(_wasCameraActiveBeforePause, _wasMicrophoneActiveBeforePause)); + } + + private IEnumerator ReconnectAfterResume(bool restoreCamera, bool restoreMic) + { + yield return ConnectToRoom(); + if (_room == null) yield break; - if (pause) _webCamTexture.Pause(); - else _webCamTexture.Play(); + if (restoreCamera) yield return PublishLocalCamera(); + if (restoreMic) yield return PublishLocalMicrophone(); } private void Update()