Why heart rate detection
Simply to prove that the client and server are still alive.When a websocket is in use, if it encounters network problems, etc., the server does not trigger the onclose event at this time, which will result in redundant connections, and the server will continue to send messages to the client, causing data loss.Therefore, a mechanism is needed to detect whether the client and the server are connected properly, and heartbeat detection and reconnection cutoffs occur.
How to do heart rate detection and reconnection
The idea is:
- Every specified period of time (timer), send a data to the server, the server receives the data and then sends it to the client. Under normal circumstances, the client can listen for the data returned by the server through the onmessage event, indicating that the request is normal.
- If the client does not receive a response message from the server within the specified time, it decides that the connection is broken and closes it with websocket.close.
- This action to close the connection can be monitored by the onclose event, so within the onclose event, we can call the reconnect event to reconnect.
Specific code implementation
$(function () { var path = basePath; var jspCode = $("#userId").val(); var websocket; createWebSocket(); /** * websocket start-up */ function createWebSocket() { try { if ('WebSocket' in window) { websocket = new WebSocket((path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws")); } else if ('MozWebSocket' in window) { websocket = new MozWebSocket(("ws://" + path + "/wsCrm?jspCode=" + jspCode).replace("http", "ws").replace("https", "ws")); } else { websocket = new SockJS(path + "/wsCrm/sockJs?jspCode=" + jspCode.replace("http", "ws")); } init(); } catch (e) { console.log('catch' + e); reconnect(); } } function init() { //Callback method for successful connection establishment websocket.onopen = function (event) { console.log("WebSocket:Connected"); //Heart beat detection reset heartCheck.reset().start(); }; //Callback method to receive message websocket.onmessage = function (event) { showNotify(event.data); console.log("WebSocket:A message was received", event.data); heartCheck.reset().start(); }; //Callback method for connection errors websocket.onerror = function (event) { console.log("WebSocket:An error occurred"); reconnect(); }; //Callback method for connection closure websocket.onclose = function (event) { console.log("WebSocket:Closed"); heartCheck.reset();//runtastic Heart Rate PRO reconnect(); }; //Listen for window closing events. When the window closes, actively close the websocket connection to prevent the window from closing before the connection is broken. The server side throws an exception. window.onbeforeunload = function () { websocket.close(); }; //Close Connection function closeWebSocket() { websocket.close(); } //send message function send(message) { websocket.send(message); } } //Avoid duplicate connections var lockReconnect = false, tt; /** * websocket Reconnection */ function reconnect() { if (lockReconnect) { return; } lockReconnect = true; tt && clearTimeout(tt); tt = setTimeout(function () { console.log('Reconnecting...'); lockReconnect = false; createWebSocket(); }, 4000); } /** * websocket runtastic Heart Rate PRO */ var heartCheck = { timeout: 5000, timeoutObj: null, serverTimeoutObj: null, reset: function () { clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function () { var self = this; this.timeoutObj && clearTimeout(this.timeoutObj); this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); this.timeoutObj = setTimeout(function () { //This sends a heartbeat, and when the back end receives it, it returns a heartbeat message. //onmessage gets the returned heartbeat and the connection is OK websocket.send("HeartBeat"); console.log('ping'); self.serverTimeoutObj = setTimeout(function () { // If it hasn't been reset for more than a certain time, the backend is actively disconnected console.log('Shut down services'); websocket.close();//If onclose executes reconnect, we just execute websocket.close(). }, self.timeout) }, this.timeout) } }; });