Skip to content

Conversation

@feldblick
Copy link

@feldblick feldblick commented Dec 4, 2025

Changed the WebSocket ping/pong implementation to use proper WebSocket protocol frames rather than sending text "ping"/"pong" messages. The server was responding to WebSocket protocol pings, not text messages, causing the previous implementation to fail silently.

Changes:

  • Replaced this.ws.send("ping") with this.ws.ping() to send protocol-level ping frames
  • Updated pong listener from this.ws.pong assignment to proper event listener this.ws.on('pong', this.onPong) for the 'ws' library
  • Added conditional check for this.ws.on method availability before attaching pong listener to ensure compatibility

This ensures the client correctly implements the WebSocket ping/pong heartbeat mechanism as defined in RFC 6455, allowing proper connection health monitoring.


Note

Switches the client to protocol-level ping/pong with a guarded 'pong' event listener for compatibility with the ws library.

  • Client WebSocket heartbeat (src/client.ts):
    • Replace text-based this.ws.send("ping") with protocol-level this.ws.ping(...).
    • Attach pong handler via this.ws.on('pong', this.onPong) (only if on exists); remove direct this.ws.pong assignment.
    • Maintain ping cycle: start on open and continue on pong.

Written by Cursor Bugbot for commit 04ada4a. This will update automatically on new commits. Configure here.

Changed the WebSocket ping/pong implementation to use proper WebSocket
protocol frames rather than sending text "ping"/"pong" messages. The
server was responding to WebSocket protocol pings, not text messages,
causing the previous implementation to fail silently.

Changes:
- Replaced `this.ws.send("ping")` with `this.ws.ping()` to send
  protocol-level ping frames
- Updated pong listener from `this.ws.pong` assignment to proper event
  listener `this.ws.on('pong', this.onPong)` for the 'ws' library
- Added conditional check for `this.ws.on` method availability before
  attaching pong listener to ensure compatibility

This ensures the client correctly implements the WebSocket ping/pong
heartbeat mechanism as defined in RFC 6455, allowing proper connection
health monitoring.
@feldblick feldblick requested a review from a team as a code owner December 4, 2025 10:02

this.ws.send("ping", (err: Error | undefined) => {
this.ws.ping((err: Error | undefined) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Ping method unavailable in browser WebSocket environments

The code uses isomorphic-ws for cross-platform WebSocket support, but the this.ws.ping() method only exists in the Node.js ws library, not in browser WebSocket implementations. While the code correctly checks if (this.ws.on) before attaching the pong listener (acknowledging browser incompatibility), no equivalent check exists for this.ws.ping(). In browser environments, calling this.ws.ping() will fail because the method doesn't exist, breaking the heartbeat mechanism entirely.

Additional Locations (1)

Fix in Cursor Fix in Web

@nopsled
Copy link

nopsled commented Dec 6, 2025

Did this solve the issue with the freeze after around 20 minutes you mentioned before where the datastream stopped? @feldblick

@feldblick
Copy link
Author

No unfortunately not. It just sends out the necessary ping properly.

The automatic review might be right though. I tested it with the ws lib. Isomorphic-ws cannot handle ping pong properly as it seems but I haven't digged deeply into it.

@nopsled
Copy link

nopsled commented Dec 6, 2025

Ran it for approx 12 hours and here are some statistics:

{
"current": {
"isConnected": true,
"connectedAt": 1765044903922,
"connectionDurationMs": 1889656,
"connectionDurationFormatted": "31m 29s",
"messagesReceived": 1376939,
"tradesReceived": 1376903,
"lastDataMessageAt": 1765046792878,
"secondsSinceLastData": 0,
"timeSinceLastDataFormatted": "0s",
"pingsSent": 11544,
"pongsReceived": 11544,
"pingSuccessRate": "100.0%",
"lastPingAt": 1765046789247,
"lastPongAt": 1765046789247,
"freezeWarnings": 35,
"reconnectAttempts": 0,
"errorEvents": 0,
"closeEvents": 35,
"healthStatus": "🟢 Healthy"
}
}

Time span monitored: ~11.5 hours
Freeze happening every 14-63 minutes (average ~30 min)
Average time between freezes: ~30 minutes

One temporary way to handle this is with 10-minute proactive reconnect:
3-4 seconds of downtime every 10 minutes = 6 reconnects/hour
In a 24-hour period: 144 reconnects × 3.5 sec = ~8 minutes of planned downtime
No surprise freezes since you're reconnecting before they happen

We should try to find a way to get the socket connection stable.

@feldblick
Copy link
Author

Ran it for approx 12 hours and here are some statistics:

{ "current": { "isConnected": true, "connectedAt": 1765044903922, "connectionDurationMs": 1889656, "connectionDurationFormatted": "31m 29s", "messagesReceived": 1376939, "tradesReceived": 1376903, "lastDataMessageAt": 1765046792878, "secondsSinceLastData": 0, "timeSinceLastDataFormatted": "0s", "pingsSent": 11544, "pongsReceived": 11544, "pingSuccessRate": "100.0%", "lastPingAt": 1765046789247, "lastPongAt": 1765046789247, "freezeWarnings": 35, "reconnectAttempts": 0, "errorEvents": 0, "closeEvents": 35, "healthStatus": "🟢 Healthy" } }

Time span monitored: ~11.5 hours Freeze happening every 14-63 minutes (average ~30 min) Average time between freezes: ~30 minutes

One temporary way to handle this is with 10-minute proactive reconnect: 3-4 seconds of downtime every 10 minutes = 6 reconnects/hour In a 24-hour period: 144 reconnects × 3.5 sec = ~8 minutes of planned downtime No surprise freezes since you're reconnecting before they happen

We should try to find a way to get the socket connection stable.

Let's continue here with the discussion, as I don't think it's ping pong related: #26

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants