Created
January 18, 2019 16:04
-
-
Save macedd/aba7791ef9504c1184769ce401f478dc to your computer and use it in GitHub Desktop.
WebSockets heartbeat implementation (nodejs + browser)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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