Repository navigation
fix: realtime protocol correctness (join, ack, heartbeat, tls) - #42
Merged
Merged
Conversation
Merged
zoedsoupe
added a commit
that referenced
this pull request
Oct 19, 2026
🚀 Want to release this? --- ## [0.6.0](v0.5.0...v0.6.0) (2026-10-16) ### Features * filter builder, select, heartbeat telemetry and presence fixes ([#44](#44)) ([6fa0dae](6fa0dae)) * rejoin backoff, duplicate binding dedup and aligned binding ids ([#46](#46)) ([ce458d9](ce458d9)) * serializer behaviour and vsn 2.0.0 binary framing ([#43](#43)) ([3aec1d6](3aec1d6)) ### Bug Fixes * realtime protocol correctness (join, ack, heartbeat, tls) ([#42](#42)) ([73548ac](73548ac)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
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.
Problem
The client could not hold a subscription correctly:
send_message/2that does not exist, so every subscribe and unsubscribe crashed it.client.apikey, which does not exist, raising a KeyError in the common anon-key case.:joinedlocally while the server had nothing.wait_for_ack/2always timed out.verify_none.Solution
Fix the join flow (route sends through the Connection, flat join payload with uppercase events and access token, correct incoming nesting, dispatch by inner event, rejoin on reconnect), the ack flow (preserve the ack ref, own the timeout timer in the Connection), the connection lifecycle (single heartbeat timer, dead-heartbeat detection, stepped backoff, unified down path, stale-message guards), token resolution, and TLS (
verify_peerwith system CAs and a hostname check, plus a:tls_optsescape hatch). Give each client its own ETS table and persist the auth token across reconnects.Rationale
Each item is a correctness bug against the phoenix/realtime protocol, so the fixes follow the server semantics rather than patching symptoms. Joins and leaves get dedicated Connection calls because the generic send path buffers anything sent while a channel is joining, which would buffer the join itself. Late postgres_changes and presence bindings now return
{:error, :already_joining | :already_joined}, matching realtime-js 2.101+, because phoenix has no add-binding push and buffering them has no correct delivery mechanism.