Repository navigation
fix: websocket close codes, backoff, app lifecycle, no reconnect on unchanged identity - #54
Merged
Merged
Conversation
…nchanged identity Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 11, 2026
Merged
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.
Why
Server diagnostics (EU, 2026-10-11):
What the code did (
GleapWebSocketHelper.m/GleapSessionHelper.m):[webSocketTask cancel], which sends no close code. The server logs that as 1005.Changes (public API unchanged)
All socket state stays on one serial queue, the main queue, where the socket's answers, timers and lifecycle notifications already arrive. Calls from other threads hop over to it.
cancelWithCloseCode:reason:. It sends 1000 (normal) when it replaces or drops a socket and 1001 (going away) when the app stays in the background.NWPathMonitor, soNetworkis now linked inPackage.swiftand the podspec.UIApplicationDidEnterBackgroundNotificationthe socket gets a 10 s grace, then closes with 1001. A background task gives the close frame time to go out, and the grace is cancelled if the app returns.WillEnterForeground/DidBecomeActiveit reconnects, debounced.connectToURL:now only asks for a channel. The socket opens 1.5 s after the last ask, so a session start followed by an identify opens one socket. If a socket is already open or opening for the same channel (same gleapId, gleapHash, apiKey and URL; query order doesn't matter), it is kept.The rules live in the new internal, stateless
GleapWebSocketPolicy(Sources/Internal, hidden like the other internal classes): the connect decision, the reconnect delay and the backoff reset.Expected effect
On new SDK versions this should mean:
Old SDK versions are mitigated server-side separately.
Testing
Tests/GleapTests/GleapWebSocketTests.swift(6 tests):connectToURL:opens no socket for the new channel; after returning to the foreground it connects.github/scripts/test.sh(xcodebuild test, iPhone 17 Pro simulator, iOS 26.4): all 132 tests pass, including the existingtestTheWebSocketCarriesTheSessionCredentials, which now covers the debounced connect.pod lib lint Gleap.podspec --allow-warnings --quickpasses. The full lint runs in CI.No version bump and no release. That goes through the SDK release process later.
🤖 Generated with Claude Code