mobile: messages stop arriving after brief background/screen-lock until app is force-killed (zombie socket on resume)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Symptom
On iOS, after backgrounding the app briefly (app switch or screen lock), new channel messages no longer render on resume. The channel list and threads stay frozen until the app is force-killed and reopened. macOS desktop is unaffected (never suspends).
## Root cause
`RelaySessionNotifier.onAppResumed` (mobile/lib/shared/relay/relay_session.dart) early-returns when the background stint was shorter than the grace window AND `state.status == SessionStatus.connected`. But the transport can be half-open after even a brief suspend: iOS drops the network on screen lock or rebinds NAT on a Wi-Fi/cellular switch, and no close frame ever reaches the client (the Dart VM is frozen, so the grace timer that would have disconnected cleanly never fired either). The status flag still says connected, the early return keeps the dead socket, live subscriptions stay silent, and nothing ever triggers the (existing, correct) reconnect+replay machinery.
The wall-clock guard added for long background stints does not cover this case: the stint is short, the socket is dead anyway.
## Repro
1. iOS device, open a channel.
2. Background the app for a few seconds (or lock the screen), in conditions where the transport drops (screen lock on Wi-Fi is a reliable trigger).
3. From another client, post to the channel.
4. Resume the app: the message never appears. Force-kill + reopen: it appears.
## Proposed fix
On the early-return path, verify liveness instead of trusting the flag: a minimal REQ that resolves on EOSE (3s timeout). On timeout/error, call `reconnect()`, which already replays live subscriptions with the since-skew. PR incoming.
Contributor guide
Assessment
This issue has not been assessed yet.