Fix WebSocket connection loss detection for AMQP channels and consumers#152
Merged
Fix WebSocket connection loss detection for AMQP channels and consumers#152
Conversation
Copilot
AI
changed the title
[WIP] Connection with websocket in browser : How to handle connection lost
Fix WebSocket connection loss detection for AMQP channels and consumers
Sep 9, 2025
8624e8f to
bf124af
Compare
32fc0eb to
46de92f
Compare
baelter
approved these changes
Sep 11, 2025
Comment on lines
+62
to
+84
| socket.addEventListener('error', (ev: Event) => { | ||
| if (!this.closed) { | ||
| const err = new AMQPError(ev.toString(), this) | ||
| this.closed = true | ||
| // Close all channels and their consumers when there's an error | ||
| this.channels.forEach((ch) => ch?.setClosed(err)) | ||
| this.channels = [new AMQPChannel(this, 0)] | ||
| this.onerror(err) | ||
| } | ||
| }) | ||
| socket.addEventListener('close', (ev: CloseEvent) => { | ||
| const clientClosed = this.closed | ||
| this.closed = true | ||
| if (!ev.wasClean && !clientClosed) this.onerror(new AMQPError(`connection not cleanly closed (${ev.code})`, this)) | ||
| if (!(ev.wasClean && clientClosed)) { | ||
| const err = new AMQPError(`connection not cleanly closed (${ev.code})`, this) | ||
| // Close all channels and their consumers when connection is lost | ||
| this.channels.forEach((ch) => ch?.setClosed(err)) | ||
| this.channels = [new AMQPChannel(this, 0)] | ||
| this.onerror(err) | ||
| } else { | ||
| this.channels.forEach((ch) => ch?.setClosed()) | ||
| this.channels = [new AMQPChannel(this, 0)] | ||
| } |
Contributor
There was a problem hiding this comment.
A little repetetive. Don't we want to do this for regular tcp clients as well? Consolidate to the base class maybe?
| } | ||
| } | ||
| }, | ||
| envDir: '.' |
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.
When using AMQP over WebSockets with a TCP relay, connection loss was not properly detected, leaving connections, channels, and consumers in an inconsistent "not closed" state. This made it impossible for applications to detect when the underlying WebSocket connection was lost and implement proper reconnection logic.
Problem
The issue occurred when the WebSocket TCP relay process stopped or network connectivity was interrupted. While the WebSocket connection would close, the AMQP connection, channels, and consumers would remain in an "open" state, making it appear as if they were still functional when they were actually disconnected.
Solution
Enhanced the
AMQPWebSocketClientto properly handle WebSocket connection loss by:closeorerrorevents occur, all active channels are now properly closed with error informationclosedstates are correctly updatedwait()promises now properly reject when connection is lostUsage
Applications can now detect connection loss in multiple ways:
The fix ensures that when a WebSocket connection is lost:
connection.closedbecomestruechannel.closedbecomestrue)wait()promises rejectFixes #111.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.