In my Expo (React Native) project, I am working on implementing a protocol to manage stale websocket connections on both the client and server sides. The 'ws' package offers built-in callback handling for the 'pong' event (and sending pings), making server-side management in NodeJS relatively straightforward.
However, I'm encountering difficulties with the client side. The native WebSocket
object does not provide a callback function for responding to pings from the server. Although it does respond correctly to server pings with opcode 0x9
, these messages are not captured by the WebSocket.onmessage
handler.
Below is my current attempt at a client-side ping handler:
const heartbeat = () => {
console.log("heartbeat");
clearTimeout(pingTimeout!);
pingTimeout = setTimeout(() => {
socket.close();
setResetConnection(rc => !rc);
}, HEARTBEAT_INTERVAL + HEARTBEAT_LATENCY);
};
socket.onmessage = (event) => {
console.log("message");
if (event.data instanceof Blob) {
console.log("received ping");
heartbeat();
const response = new ArrayBuffer(1);
const view = new Uint8Array(response);
view[0] = 0x9;
socket.send(view);
return;
}
[...remaining onmessage code...]
}
The socket
is initialized as
var socket = new WebSocket("ws://ipaddr:8080");
As noted, the pong is sent back to the server automatically without giving the client any opportunity for additional logic. I am currently looking for a way to override this default behavior without having to create my own ping/pong protocol.