Reputation: 10473
I keep reading about ping/pong messages in websockets to keep the connection alive, but I'm not sure what they are. Is it a distinct frame type? (I don't see any methods on a javascript WebSocket object in chrome related to ping-pong). Or is it just a design pattern (e.g. I literally send "ping" or any other string to the server and have it respond). Is ping-pong at all related to continuation frames?
The reason I ask is I'm using a python framework that runs behind Mongrel2, so I'm wondering if there's a way to send Mongrel2 a specific ping/pong message that would tell it to keep the connection alive without my python app needing to worry about it. Analogous to a having a separate HTTP method for it, I guess. And I imagine a dedicated ping/pong message frame could be simpler (less load on server and network) than the string "ping", though that probably wouldn't matter too much.
EDIT: I just looked at RFC 6455 and it looks like Ping and Pong are definitely control frame types with their own opcodes. So how do I send a Ping frame from javascript in Chrome?
Upvotes: 189
Views: 204461
Reputation: 2568
Currently (year 2024), you don't need to send pings from browser manually, as it is handled automatically in major browsers. You only need to handle pong's from the server side.
The rationale is that developer usually has no information about user's network quality and status, but browser does, so it's better to let browser to decide on the optimal frequency to send pings.
If you not happy with the browser's decisions on the matter, you can send additionally some heartbeat messages, but you cannot decrease the frequency of the browser-initiated pings as far as I know, besides telling the user to change the browser config (some browsers have internal settings for websockets).
Edit 2024-08-18
As @orooney pointed out, actual behaviour of the keepalive/ping can differ substantially in browsers, i.e. Firefox can detect dead websocket within 10-20 seconds and issue an 'onclose' event, while Chromium can consider websocket alive for tens of minutes after network disconnection
Upvotes: -3
Reputation: 12176
An alternative JavaScript solution that sends an empty data frame, rather than a ping frame:
In case of the WebSocket server initiative disconnects the
ws
link after a few minutes there were no messages be sent between the server and client.
the client end initiative sends a custom ping
message, to keep alive by using the keepAlive
function
the server end will ignore the custom ping
message and responds to a custom pong
message
let timerId = 0;
function keepAlive(timeout = 20000) {
if (webSocket.readyState == webSocket.OPEN) {
webSocket.send('');
}
timerId = setTimeout(keepAlive, timeout);
}
function cancelKeepAlive() {
if (timerId) {
clearTimeout(timerId);
}
}
Upvotes: 8
Reputation: 3073
No.
I attempted to implement a ping. There doesn't seem to be any way I can force a browser WebSocket client to set any opcode other than 0x1 (string) and 0x2 (binary).
const socket = new WebSocket(url);
ping() {
if (socket?.readyState !== WebSocket.OPEN) {
return;
}
const buffer = new ArrayBuffer(7);
const dataView = new DataView(buffer);
dataView.setInt8(0, 0x89);
dataView.setInt8(1, 0x00);
dataView.setInt8(2, 0x48);
dataView.setInt8(3, 0x65);
dataView.setInt8(4, 0x6c);
dataView.setInt8(5, 0x6c);
dataView.setInt8(6, 0x6f);
socket.send(buffer);
}
socket.addEventListener('open', ping);
This code should send a final (0x8) ping frame (opcode 0x09) with body "hello", but the browser sends a final frame in binary (0x82) that has body "�hello" where � is the 0x89 data.
Upvotes: 7
Reputation: 23047
Update: Although the answer is old, it's in google's top results. At any point after the handshake, either the client or the server can choose to send a ping to the other party
Ping is meant to be sent only from server to client, and browser should answer as soon as possible with Pong OpCode, automatically. So you have not to worry about that on higher level.
Although that not all browsers support standard as they suppose to, they might have some differences in implementing such mechanism, and it might even means there is no Pong response functionality. But personally I am using Ping / Pong, and never saw client that does not implement this type of OpCode and automatic response on low level client side implementation.
Upvotes: 14
Reputation: 73119
There is no Javascript API to send ping frames or receive pong frames. This is either supported by your browser, or not. There is also no API to enable, configure or detect whether the browser supports and is using ping/pong frames. There was discussion about creating a Javascript ping/pong API for this. There is a possibility that pings may be configurable/detectable in the future, but it is unlikely that Javascript will be able to directly send and receive ping/pong frames.
However, if you control both the client and server code, then you can easily add ping/pong support at a higher level. You will need some sort of message type header/metadata in your message if you don't have that already, but that's pretty simple. Unless you are planning on sending pings hundreds of times per second or have thousands of simultaneous clients, the overhead is going to be pretty minimal to do it yourself.
Upvotes: 165