Reap a phone whose companion link died without a FIN - #298
Open
jiweiyuan wants to merge 1 commit into
Open
Conversation
A phone that leaves coverage or sleeps never sends a FIN, so its half-open socket stays on the books for minutes — and its bridge still owns the PTY's winsize, leaving the Mac's window sized to a phone that is gone. The server now enables TCP keepalive, records the last frame heard from each connection, and drops one silent past 50s. A tick that arrives late (the Mac slept, or the main runloop stalled) forgives the gap instead of reaping every phone at once. The phone closes the same loop from its end: the socket waits for connectivity rather than failing instantly and burning a backoff step, reconnects the moment the network path returns instead of sitting out the heartbeat, and holds the "Reconnecting…" banner through the fast retry burst so a blip does not read as an outage. Its frame cap rises to match the server's 16 MB, since a cap below the peer's turns any oversized frame into an unexplained reconnect.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A phone that leaves coverage or sleeps never sends a FIN, so its half-open socket stays on the books for minutes — and its bridge still owns the PTY's winsize, leaving the Mac's window sized to a phone that is gone.
The Mac now enables TCP keepalive, records the last frame heard from each connection, and drops one silent past 50s. A tick that arrives late (the Mac slept, or the main runloop stalled) forgives the gap instead of reaping every phone at once.
The phone closes the same loop from its end.
CompanionTransportgains the 15s ping timer andNWPathMonitorthatCompanionClientalready had, so a half-open terminal socket is noticed instead of looking frozen, and a network switch reconnects immediately instead of sitting out the 30s heartbeat. Its frame cap rises to the server's 16 MB, since a cap below the peer's turns any oversized frame into an unexplained reconnect.Compatibility with shipped phones
The 50s reap counts any received frame as proof of life, so it must not kill a TestFlight 1.1 phone that predates the client-side ping. Verified against a Network.framework listener built to mirror
CompanionServer.start()(autoReplyPing = true, same receive pump, same 20s ping), with a client that never initiates a ping and never sends data:NWConnectionsurfaces the pong to the receive handler, solastHeardrefreshes every 20s on a link that sends nothing at all — two refreshes inside the 50s limit. A pong also falls through todefault: breakrather than being decoded as a control frame, and the pump re-arms outside the opcode switch, so it cannot end the receive loop.Release Notes