fix: use shutdown_timeout so QUIC CONNECTION_CLOSE actually gets sent

shutdown_background() killed the tokio runtime before quinn could send the
CONNECTION_CLOSE frame on the wire, so the relay never knew the client left.
Now use shutdown_timeout(500ms) to give quinn time to flush the close frame,
matching the desktop client pattern (which uses 2s timeout).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude
2026-04-06 05:20:20 +00:00
parent dc66b60d18
commit 9bbaec6b35

View File

@@ -149,14 +149,18 @@ impl WzpEngine {
pub fn stop_call(&mut self) {
self.state.running.store(false, Ordering::Release);
// Close QUIC connection immediately so the relay detects disconnect
// and removes us from the room (broadcasts RoomUpdate to others).
// Close QUIC connection first — queues a CONNECTION_CLOSE frame.
// Quinn needs the tokio runtime alive to actually send it on the wire,
// so we use shutdown_timeout() to give it time to flush.
if let Some(transport) = self.state.quic_transport.lock().unwrap().take() {
transport.close_now();
}
let _ = self.state.command_tx.send(EngineCommand::Stop);
if let Some(rt) = self.tokio_runtime.take() {
rt.shutdown_background();
// Give quinn up to 500ms to send the CONNECTION_CLOSE frame.
// The desktop client uses 2s, but we keep it short on Android
// to avoid blocking the UI thread.
rt.shutdown_timeout(std::time::Duration::from_millis(500));
}
self.call_start = None;
}