Skip to content

Instantly share code, notes, and snippets.

@macedd
Created January 18, 2019 16:04
Show Gist options
  • Save macedd/aba7791ef9504c1184769ce401f478dc to your computer and use it in GitHub Desktop.
Save macedd/aba7791ef9504c1184769ce401f478dc to your computer and use it in GitHub Desktop.
WebSockets heartbeat implementation (nodejs + browser)
/**
* Tracks server pings for determining if the connection dropped.
* Will terminate non-responsive connections.
* This close event should initiate the process of recreating the connection in the ws module manager (eg ws/user.js and modules/ws-user.js)
*/
function setupWsHeartbeat(ws) {
// will close the connection if there's no ping from the server
function heartbeat() {
clearTimeout(this.pingTimeout);
// Use `WebSocket#terminate()` and not `WebSocket#close()`. Delay should be
// equal to the interval at which server sends out pings plus an assumption of the latency.
this.pingTimeout = setTimeout(() => {
this.terminate();
}, 30000 + 1000);
}
ws.on('open', heartbeat);
ws.on('ping', heartbeat);
ws.on('close', function clear() {
clearTimeout(this.pingTimeout);
});
}
function createWebSocketConnection(endpoint) {
const ws = new WebSocket(endpoint);
ws.onopen(ev => console.log('Websocket open', ev));
ws.onmessage(ev => console.log('Websocket message', ev));
// heartbeat will check connection is alive
setupWsHeartbeat(ws);
return ws;
}
createWebSocketConnection('ws://localhost:5000');
/**
* Will ping clients in a interval and terminate broken connections
*/
function setupWsHeartbeat(wss) {
function noop() {}
function heartbeat() {
this.isAlive = true;
}
wss.on('connection', function connection(ws) {
ws.isAlive = true;
ws.on('pong', heartbeat);
});
const interval = setInterval(function ping() {
wss.clients.forEach(function each(ws) {
// client did not respond the ping (pong)
if (ws.isAlive === false) return ws.terminate();
ws.isAlive = false;
ws.ping(noop);
});
}, 30000);
}
const wsInstance = WebSocket.Server({});
setupWsHeartbeat(wsInstance);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment