My dev blog where I dive deep into TypeScript, Postgres, Data science, Infrastructure, Ethereum, and more...

Pings and pongs in WebSocket — There are two different types!

22nd Jun 2024

When building a real-time WebSocket server you often use a ping and pong message to verify that the connection is still open.

Send a “ping” from one end, return a “pong” from the other end. This is often done regularily and called a “heartbeat”.

As I started implementing WebSocket servers and clients, I got confused. Sometimes pings and pongs are handled by libraries, sometimes not.

I learnt that there are actually two different types of pings/pongs. Some are implemented at the protocol level, and others are optionally done at the application level. It can be useful to understand the difference.

Payload
Level
Who sends it?
Ping frame (0x9)
Protocol
Sent from server
Pong frame (0xA)
Protocol
Responded from client
“ping” string
Application
Sent from client
“pong” string
Application
Responded from server

The server sends a ping frame, the client responds with a pong frame

In the WebSocket spec (RFC-6455), the concepts of Ping frames and Pong frames are defined.

  • A ping frame is a WebSocket payload that contains the data: 0x9.
  • A pong frame is a WebStocket payload that contains the data: 0xA.

Ping frames are sent from the WebSocket server. The client (typically a browser), should respond as quickly as possible with a pong frame.

The browser never sends a ping frame!

In a browser, you can’t even see or log ping and pong frames, they are handled automatically under-the-hood. And there is no way to manually send these frame in the browser.

What if I want to ping from the client?

Ping/pong frames are useful for the server to close stale connections. But sometimes, the server goes down or becomes overloaded. In these cases, it can be useful for the browser (client) itself, to ping the websocket and try to re-initiate the connection.

Since the client does not have access to send low-level ping/pong frames, we need to implement this in a more custom way. Typically this is done by sending “ping” and “pong” as strings, but in practice you could choose any data.

Since this is not a part of any standard, we need to add code to our server to recognize this approach.

If no “pong” is received from the server, it’s an indication to the client that something is wrong with the connection.

Conclusion

Pings and pongs are useful for keeping WebSocket connections alive and healthy.

Keep in mind the differences between protocol level pings/pongs, and ping/pongs you’ll need to implement yourself.

“ping” ——————————————— “pong”!


Tools