On the micro-channel and achieve applet websocket heartbeat reconnection

In use

was ws = new WebSocket (URL);
ws.onclose = function () {
    //something
};
ws.onerror = function () {
    //something
};
        
ws.onopen = function () {
   //something
};
ws.onmessage = function (event) {
   //something
}
Copy the code

Micro-channel applet websocket process may occur off the network, such as a bad signal, or network temporary closed, this time websocket connection has been disconnected,

The browser will not execute onclose websocket method, we can not know whether disconnected, it can not re-connect operations.

If the current websocket send data to the back end, once the request times out, onclose will perform, this time can be bound to good reconnection operation.

Therefore websocket heart reconnection is made.

 

How to achieve

In websocket instantiated, we will bind some of the events:

Copy the code
was ws = new WebSocket (URL);
ws.onclose = function () {
    //something
};
ws.onerror = function () {
    //something
};
        
ws.onopen = function () {
   //something
};
ws.onmessage = function (event) {
   //something
}
Copy the code

If you want to keep websocket connection, we will be bound in close or reconnect error method.

Copy the code
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
    
Copy the code

Under normal circumstances this time the connection is lost, triggering onclose approach, we will be able to perform a reconnection.

 

So for the case of off network heartbeat reconnect, how to achieve it.

Simple implementation:

Copy the code
was heart check = {
    timeout: 60000,//60ms
    timeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
     this.start(); }, start: function(){ this.timeoutObj = setTimeout(function(){ ws.send("HeartBeat"); }, this.timeout) } } ws.onopen = function () { heartCheck.start(); };
ws.onmessage = function (event) {
    heartCheck.reset();
}
Copy the code

As the code, heartCheck the reset and start method is mainly used to control the timing of a heartbeat.

Execution heartbeat under what conditions:

When the connection is onopen when we began to start counting, if within the timing range, onmessage get to the back end of the message, we will reset the countdown,

After obtaining the distance from the rear end of the last message to more than 60 seconds, heartbeat performed to see whether the disconnection, the detecting time can be set according to their own situation.

Analyzing distal ws opened (off-net, but are not limited to the case of disconnection):

When the send heartbeat detection method execution, if the current state websocket is off (or off the net), after sending a timeout, the browser will automatically trigger ws onclose method, reconnect also performed (onclose bound method body weight even event), if the current network state has been broken, will reconnect two seconds (a time code setting their own) to perform a normal network until a successful connection.

Thus, we determine the front-end initiative calls on the heartbeat ws achieved. Why is the front-end initiative calls, mainly because of the current circumstances through the front ws events to judge, saying the situation behind the initiative off the back end.

 

I wanted to test websocket timeout, and found some new problems

1. In the chrome, then if the heartbeat is websocket instance as send, within 15 seconds, the other is not transmitted to the receiving end, it performs the OnClose. So timeout is 15 seconds.

2. I opened Firefox, Firefox 7 seconds after the disconnection, direct execution onclose. Indicates not heartbeat can be automatically onclose in Firefox.

3. The same code, reconnect the implementation of a method in chrome, Firefox executed twice. Of course, we are in a few places (code logic at the event and at websocket) bound to reconnect (),

So be safe, we give reconnect () method to add a lock to ensure that only executed once

 

Now, different browsers have different mechanisms, regardless of the browser will not execute its own websocket onclose In case off network, plus heartbeat after reconnection, has been able to ensure the normal trigger onclose.

 

Determine the back-end disconnect:

    If the backend because of some circumstances disconnected ws, is then under controlled circumstances, it would send a message disconnection notice, only after the disconnection, we will reconnect.

If for some unusual disconnected, we are not sensitive to, so if we send a heartbeat after a certain time, neither the backend heartbeat response message is returned, the front has not received any other information, we can conclude initiative calls for the backend.

Is especially important to send a message after the heartbeat must be returned to the back-end, back-end message is received, otherwise it will take the initiative to determine the back-end disconnected after more than 60 seconds. Then transformation under the code:

 

Copy the code
was heart check = {
    timeout: 60000,//60ms
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
     this.start();
    },
    start: function(){
        var self = this;
        this.timeoutObj = setTimeout(function(){
            ws.send("HeartBeat");
            self.serverTimeoutObj = setTimeout(function(){
                ws.close ();. // If onclose performs reconnect, we execute ws.close () on the line if the direct execution will trigger onclose lead to reconnect reconnection twice
            }, self.timeout)
        }, this.timeout)
    },
}

ws.onopen = function () {
   heartCheck.start();
};
ws.onmessage = function (event) {
    heartCheck.reset();
}
ws.onclose = function () {
    reconnect();
};
ws.onerror = function () {
    reconnect();
};
 
Copy the code

 

PS:

    Currently this way because we would have been if the reconnection is not connected or disconnected, and if there are two devices at the same time the other end of the landing and will kick off the assembly line, be sure to send a message to kick off the assembly line type, received here this types of messages, no longer performs logical judgment after reconnect, otherwise there will be endless loop of a mutual squeeze off the assembly line.

Guess you like

Origin www.cnblogs.com/lanshu/p/11837084.html