Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.


One, foreword

Stepping on the tail of the end of the year, the layout of the next year in advance, for the next year’s work to lay a good foundation, so I started the interview process, because WebSocket was used in the project, the interviewer when digging into the project experience, it is inevitable to mention websocket-related knowledge points, because I had not considered so deeply, so, The answer is still lack of, therefore, quickly while it is hot to be familiar with, also take this opportunity to sort out for everyone to chew, each project has its worth digging flash point, to use loving eyes 👁 to find.

What is WebSocket

WebSocket is a protocol for full duplex communication over a single TCP connection. WebSocket makes it easier to exchange data between the client and the server, allowing the server to actively push data to the client.

In the WebSocket API, the browser and server only need to complete a handshake to create a persistent connection and two-way data transfer. (Wikipedia)

WebSocket is a computer network application layer protocol in essence, used to make up for the HTTP protocol in the persistent communication capability.

WebSocket protocol was born in 2008 and became an international standard in 2011. It is now supported by the latest browsers.

Its biggest characteristic is that the server can take the initiative to push information to the client, the client can also take the initiative to send information to the server, is a real two-way equal dialogue, belongs to a server push technology.

Other features of WebSocket include:

(1) Based on THE TCP protocol, the implementation of the server side is relatively easy.

(2) It has good compatibility with HTTP protocol. The default ports are also 80 and 443, and the handshake phase uses HTTP protocol, so it is not easy to mask the handshake and can pass various HTTP proxy servers.

(3) The data format is relatively light, the performance overhead is small, and the communication is efficient.

(4) Can send text, can also send binary data.

(5) There is no source restriction, and the client can communicate with any server.

(6) The protocol identifier is WS (if encrypted, WSS), and the server URL is the URL.

ws://example.com:80/some/path
Copy the code

Why WebSocket?

We already have HTTP, why do we need another protocol? What good can it do?

Because HTTP protocol has a defect: the communication can only be initiated by the client, there is no server push capability.

For example, if we want to query today’s real-time data, we can only ask the client to the server, and the server returns the query results. The HTTP protocol does not allow the server to actively push information to the client.

The nature of this one-way request makes it very difficult for the client to know if the server has continuous state changes. We can only use “polling” : every once in a while, we issue a query to see if the server has any new information. The most typical scenario is a chat room. Polling is inefficient and wasteful (because you have to keep connecting, or HTTP connections are always open).

Before the emergence of WebSocket protocol, creating a Web application that communicates with the server in two channels requires constant polling based on HTTP protocol, which leads to some problems:

  • The server is forced to maintain a large number of different connections from each client
  • A large number of polling requests can cause high overhead, such as redundant headers, resulting in useless data transfer.

HTTP protocol itself has no persistent communication capability, but we need this capability in practical applications. Therefore, in order to solve these problems, WebSocket protocol was born from this, and was set as standard RFC6455 by IETF in 2011, and was supplemented by RFC7936.

And the RELEVANT API of WebSocket protocol is added in THE HTML5 standard, so as long as the client of HTML5 standard is realized, it can carry on the full-duplex persistent communication with the server that supports WebSocket protocol.

Differences between WebSocket and HTTP

WebSocket vs. HTTP:

Similarities: Both protocols are based on TCP and are reliable transmission protocols. Both are application layer protocols.

Contact: When WebSocket establishes a handshake, data is transmitted over HTTP. However, once established, the HTTP protocol is not required for actual transmission.

The following chart illustrates the main differences between HTTP and WebSocket:

1, WebSocket is a two-way communication protocol, simulated Socket protocol, can two-way send or receive information, and HTTP is one-way; 2. WebSocket requires a handshake between the browser and the server to establish a connection, while HTTP is the connection initiated by the browser to the server.

Note: although HTTP/2 also has server push capabilities, HTTP/2 can only push static resources, not specified information.

The principle of WebSocket protocol

Like HTTP, WebSocket requires an established TCP connection to transmit data. Concrete implementation is through HTTP protocol to establish channels, and then on this basis with the real WebSocket protocol for communication, so WebSocket protocol and HTTP protocol is a certain cross relationship.

First, WebSocket is a persistent protocol, as opposed to HTTP, which is not persistent. For a simple example, use the PHP life cycle, which is widely used today.

The HTTP lifecycle is defined by a Request, i.e., a Request and a Response. In HTTP1.0, the HTTP Request ends.

Improvements were made in HTTP1.1 to have a keep-alive, that is, multiple requests can be sent and multiple responses received within an HTTP connection. But remember that Request = Response, which is always the case in HTTP, means that there can only be one Response per Request. Moreover, this Response is also passive and cannot be initiated actively.

First, WebSocket is based on HTTP, or borrows HTTP to do part of the handshake.

First let’s look at a typical WebSocket handshake

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
Copy the code

Those familiar with HTTP may have noticed that there are several things in this HTTP-like handshake request.

Upgrade: websocket
Connection: Upgrade
Copy the code

This is the core of WebSocket, tell Apache, Nginx and other servers: attention, I want to use WebSocket protocol, help me find the corresponding assistant processing ~ not that old-fashioned HTTP.

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Copy the code

First of all, sec-websocket-key is a Base64 encode value, which the browser randomly generates to tell the server: Peat, don’t screw with me, I’m going to verify that you’re really a WebSocket assistant.

Sec_websocket-protocol, however, is a user-defined string used to distinguish between protocols required by different services under the URL. I’m going to serve A tonight. Make no mistake

Finally, sec-websocket-version tells the server to use the WebSocket Draft (protocol Version). At the beginning, the WebSocket protocol is still in the Draft stage, there are all kinds of weird protocols, and there are many weird and different things. Firefox and Chrome are not using the same version of the WebSocket protocol was a big problem. Everyone uses the same version: Waiter, I want a 13-year-old oh →_→

The server then returns the following message indicating that the request was received and the WebSocket was successfully established.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Copy the code

This is the final area of HTTP to tell the client that I have successfully switched protocols

Upgrade: websocket
Connection: Upgrade
Copy the code

Still fixed, the WebSocket protocol tells the client about the upcoming upgrade, not mozillasocket, lurnarsocket, or shitsocket.

Sec-websocket-accept is an encrypted sec-websocket-key that is confirmed by the server. Server: ok ok, know, show you my ID CARD to prove the line.

Sec-websocket-protocol is the final Protocol used.

At this point, HTTP has done all of its work, and now it’s all WebSocket protocol.

In summary, the process of WebSocket connection is as follows:

First, the client initiates an HTTP request and establishes a TCP connection after three handshakes. The HTTP request stores information about the Version supported by WebSocket, such as Upgrade, Connection, and websocket-version.

After receiving the handshake request from the client, the server also uses HTTP protocol to send back data.

Finally, after receiving the message that the connection is successful, the client starts to use the TCP transport channel for full-duplex communication.

4. Advantages and disadvantages of Websocket

Advantages:

  • The WebSocket protocol, once recommended, consumes very little request headers to communicate with each other
  • The server can now push messages to the client

Disadvantages:

  • A few browsers do not support it. Browsers support it in different ways (IE10)

Five,WebSocket application scenarios

  • Instant chat communication
  • Multi-player games
  • Online co-editing/editing
  • Pull and push of real-time data stream
  • Sports/games live
  • Real-time map location
  • instantWebApplications: InstantWebThe application uses oneWebThe socket displays data on the client side, which is continuously sent by the back-end server. inWebSockeIn t, data is continuously pushed/transferred to the same connection that is already open. Is that whyWebSocketFaster and improved application performance. For example, in exchange sites or bitcoin exchanges, this is the most volatile thing, it is used to show price fluctuations, and the data is continuously pushed to the client by the back end server using the Web socket channel.
  • Game applications: In a game application, you may notice that the server continues to receive data without refreshing the user interface. The user interface on the screen refreshes automatically, and there is no need to make a new connection, so inWebSocketGame apps can be very helpful.
  • Chat application: The chat application is used onlyWebSocketOnce established, messages can be exchanged, published, and broadcast between subscribers. It reuses the sameWebSocketConnections for sending and receiving messages and one-to-one message transfer.

Scenarios where WebSocket cannot be used

If we need any real-time updates or continuous streams of data over the network, we can use WebSocket. If we want to fetch old data, or if we only want to fetch data once for use by the provider, we should use HTTP. Data that does not need to be fetched very often or only once can be queried through simple HTTP requests, so it is best not to use WebSocket in this case.

Note: If the data is only loaded once, then the RESTful Web service is sufficient to fetch the data from the server.

6. Websocket is disconnected and reconnected

Heartbeat means that the client periodically sends messages to the server to prove that the client is online. If the heartbeat message is not sent within a certain period of time, the client is offline.

How to judge online and Offline?

When the client sends the request to the server for the first time, it will carry the unique identifier and time stamp. The server queries the unique identifier of the request to the DB or cache. If it does not exist, it will be stored in the DB or cache.

The second time when the client sends the request regularly, it still carries the unique identifier and time stamp. The server queries the unique identifier of the request to the DB or cache. If there is any, it takes out the last time stamp and subtracts the last time by the current time stamp.

The number of milliseconds obtained determines whether it is greater than the specified time. If it is less than the specified time, it is online; otherwise, it is offline.

How to solve the disconnection problem

By looking up information, we know that nginx proxy websocket forwarding, no message connection will be timeout disconnection problem. There are two solutions mentioned on the Internet. One is to modify nginx configuration information, and the other is to send heartbeat packets through Websocket.

The following is a summary of the solutions to the two problems of websocket disconnection and reconnection solved in the practice of this project.

Active triggering includes active disconnection, and the client actively sends messages to the back end

  1. Active disconnection
ws.close();
Copy the code

Active disconnection, use as needed, rarely used.

  1. Send messages actively
ws.send("hello world");
Copy the code

Let’s analyze websocket disconnection.

  • Possible cause 1: The websocket times out and no message is sent. Solution:

    In this case, we need to know the timeout period set by the server. To send heartbeat packets within the timeout period, there are two schemes: one is that the client actively sends upstream heartbeat packets, and the other is that the server actively sends downstream heartbeat packets.

    The following is mainly about the client side, that is, how to achieve the front-end heartbeat packet:

    First, let’s look at the heartbeat packet mechanism

    Heartbeat packets are called heartbeat packets because they are sent at regular intervals, like heartbeat, to tell the server that the client is still alive. In fact, this is to keep the connection long. As for the contents of this package, there is no special rule, but it is usually a very small package, or an empty package containing only the header.

    In the TCP mechanism, there is a mechanism for heartbeat packets, that is, the TCP option: SO_KEEPALIVE. The default heartbeat rate is set to 2 hours. But it can not check the machine power, network cable pulled out, firewall and other disconnections. And the logical layer may not be so good at handling broken lines. In general, if only for survival or can be.

    Heartbeat packets are typically implemented by sending empty Echo packets at the logical layer. The next timer sends an empty packet to the client at a certain interval, and then the client feeds back a same empty packet. If the server does not receive the feedback packet sent by the client within a certain period of time, it can only identify that it is disconnected.

    With a long connection, there may be no data coming and going for a long time. In theory, the connection is always connected, but in practice it is difficult to know if the intermediate node fails. What’s more, some nodes (firewalls) will automatically disconnect the connection without data interaction within a certain period of time. At this point, we need our heartbeat packets to maintain the long connection and keep us alive.

    Heartbeat detection procedure:

    1. The client sends a probe packet to the server at regular intervals
    2. The client starts a timeout timer when sending packets
    3. The server receives a packet and should respond with a packet
    4. If the client receives a reply packet from the server, the server is running properly and the timeout timer is deleted
    5. If the client timeout timer times out and no reply packet is received, the server hangs up
    // Front-end solution: heartbeat detection
    var heartCheck = {
        timeout: 30000.// One heartbeat every 30 seconds
        timeoutObj: null.serverTimeoutObj: null.reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(function(){
                // A heartbeat message is sent, and the back end returns a heartbeat message,
                // if onMessage receives the returned heartbeat, the connection is normal
                ws.send("ping");
                console.log("ping!")
    
                self.serverTimeoutObj = setTimeout(function(){// If it has not been reset for a certain amount of time, the backend is disconnected
                    ws.close(); // If onclose would reconnect, we would reconnect to ws.close(). A reconnect would trigger onClose and cause the reconnect to occur twice
                }, self.timeout);
            }, this.timeout); }}Copy the code
  • Possible cause 2: Websocket exceptions include server interruption, interactive screen cutting, and client interruption

    What does the client do when the server goes down and what does the server do when it comes online again?

    The client needs to disconnect and close the connection through onclose. When the server goes online again, it needs to clear the stored data. Otherwise, all requests sent to the server will be regarded as offline.

    The solution to this problem is to handle reconnections. The following solution is handled by using the JS library: reconnecting-websocket.min.js;

    var ws = new ReconnectingWebSocket(url);
    // Reconnection:
    reconnectSocket(){
        if ('ws' in window) {
            ws = new ReconnectingWebSocket(url);
        } else if ('MozWebSocket' in window) {
           ws = new MozWebSocket(url);
        } else {
          ws = newSockJS(url); }}Copy the code

    Js library: offline.min.js is supported for network outage monitoring

    onLineCheck(){
        Offline.check();
        console.log(Offline.state,'---Offline.state');
        console.log(this.socketStatus,'---this.socketStatus');
    
        if(!this.socketStatus){
            console.log('Network connection is down! ');
            if(Offline.state === 'up' && websocket.reconnectAttempts > websocket.maxReconnectInterval){
                window.location.reload();
            }
            reconnectSocket();
        }else{
            console.log('Network connection successful! ');
            websocket.send("heartBeat"); }}// Use: calls network interruption monitoring when webSocket disconnects
    websocket.onclose => () {
        onLineCheck();
    };
    Copy the code

    The above scheme is just a primer. If you have a better solution, please share it in the comments section.

Seven,

  • WebSocket is a protocol created for two-channel communication in Web applications. Compared with polling HTTP requests, WebSocket has advantages of saving server resources and high efficiency.
  • The mask in WebSocket is set to prevent problems such as intermediate cache contamination attacks in earlier versions. The mask is required for sending data from the client to the server, but the server does not need to send data from the client.
  • Sec-websocket-key generation algorithm in WebSocket is to combine the string generated by the server and the client, perform SHA1 hash algorithm, and then use Base64 encoding.
  • The WebSocket handshake relies on THE HTTP protocol, which relies on HTTP Response 101 for protocol upgrade and conversion.

Reference:

# Ruan Yifeng: WebSocket tutorial

# Let you understand the principle of WebSocket thoroughly