Why use WebSocket?

  • For our first contact with WebSocket students, in fact, we all have a question 🤔️, we have HTTP, why still use WebSocket, what are its advantages? In fact, HTTP is very simple, only by the client to send requests to the server, is one-way. WebSocket is bidirectional, the server can take the initiative to push information to the client.

What is a WebSocket?

  • WebSocket is something out of HTML5, it is a new protocol, it has nothing to do with HTTP protocol, just to be compatible with the existing browser handshake specification, that is to say, it is a supplement to HTTP protocol, we can understand through this figure.

That WebSocket is what kind of protocol, what are the specific advantages?

  • If you want to know the advantages of WebSocket, we should first understand the pain points of HTTP, don’t you think so?
  • Let’s talk about HTTP requests first
    • The HTTP lifecycle is defined by a Request, a Request, a Response, and 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.
    • Also, HTTP is a stateless protocol, and in plain English, because the server is dealing with so many people every day,More forgetfulAs soon as you left he forgot all about you. You’re gonna have to tell it who you are?
  • Let’s make it simpler in human terms
    • HTTP is one-way, and only the client can send requests to the server. However, WebSocket is bidirectional, and the server can push messages to the client directly.
    • HTTP can only be a request for a response. But a WebSocket can be a single request with multiple responses.
    • HTTP is a stateless protocol. Each time a TCP connection is established, the connection is disconnected after a request and a response. Sending the request again requires you to re-establish the TCP connection, again telling the server who you are. However, Websocket only requires one HTTP handshake, so the entire communication process is established in one connection/state, avoiding HTTP statelessness, and the server will know your information until you close the request.
    • WebSocket is inherently cross-domain, naturally encrypted.

How does WebSocket implement handshake?

  • Let’s look at the WebSocket request header first
    GET/HTTP/1.1 Host: localhost:8080 Origin: http://127.0.0.1:3000 Connection: Upgrade Upgrade: websocket Sec-WebSocket-Version: 13 Sec-WebSocket-Key: w4v7O6xFTi36lq3RNcgctw==Copy the code
  • The significance of the key request header is as follows:
    • Connection: Upgrade: indicates that the protocol is to be upgraded
    • Upgrade: WebSocket: tell the server, although I send you HTTP at the beginning, but later we Upgrade to WebSocket, ok?
    • Sec-websocket-version: 13: indicates the WebSocket Version. If the server does not support the version, you need to return an sec-websocket-versionheader containing the version number supported by the server.
    • Sec-websocket-key: verify that you are not a WebSocket. If you reply correctly, you are a WebSocket server. If you cannot reply correctly, you are a WebSocket server.
  • 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

Five. Luk the code, feel 😜

  • client
    <! DOCTYPE html> <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title></title>
        <script>
        let ws = new WebSocket('ws://localhost:8080/');
    
        ws.onopen = function (){
          alert('Connection established');
        };
        ws.onmessage=function() {}; ws.onclose=function() {}; ws.onerror=function() {}; </script> </head> <body> </body> </html>Copy the code
  • server
    const net=require('net');
    const crypto=require('crypto');
    
    functionParseHeader (STR){// all HTTP newlines are \r\n, and we want to filter out empty lineslet arr = str.split('\r\n').filter(line => line);
        arr.shift();
        
        let headers = {};
        arr.forEach(line => {
        let [name, value] = line.split(':');
    
        name = name.replace(/^\s+|\s+$/g, ' ').toLowerCase();
        value = value.replace(/^\s+|\s+$/g, ' ');
    
        headers[name] = value;
      });
    
      return headers;
    }
    
    let server = net.createServer(sock => {
      sock.once('data', buffer => {
        let str = buffer.toString();
        let headers = parseHeader(str);
    
        if (headers['upgrade'] != 'websocket') {
          console.log('no upgrade');
          sock.end();
        } else if (headers['sec-websocket-version']! ='13'){
          console.log('no 13');
          sock.end();
        } else {
          let key = headers['sec-websocket-key'];
          let uuid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
          let hash =c rypto.createHash('sha1');
    
          hash.update(key+uuid);
          let key2 = hash.digest('base64'); Sock.write (' HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection:upgrade\r\ nsec-websocket-accept:${key2}\r\n\r\n`); }}); sock.on('end', () = > {}); }); server.listen(8080);Copy the code

6. Socket. IO

  • Through IO to realize the connection between the server and client, compatible with multiple browsers.
  • client
    <! DOCTYPE html> <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title></title>
        <script src="http://localhost:8080/socket.io/socket.io.js" charset="utf-8"></script>
        <script>
        let sock = io.connect('ws://localhost:8080/');
    
        sock.on('timer', time => {
          console.log(time);
        });
        </script>
      </head>
      <body>
    
      </body>
    </html>
    Copy the code
  • server
    const http = require('http');
    const io = require('socket.io'); // 1. Set up plain HTTPletserver = http.createServer((req, res) => {}); server.listen(8080); // 2. Create wslet wsServer = io.listen(server);
    wsServer.on('connection', sock => {
      // sock.emit('name'// sock. On ()'name'.function(data) {}); /*sock.on('aaa'.function(a, b) { console.log(a, b, a+b); }); * /setInterval(function (){
        sock.emit('timer', new Date().getTime());
      }, 1000);
    });
    Copy the code

7. To summarize

  • If your application needs to provide multiple users to communicate with each other, and the data on the server side changes frequently, you should really consider using WebSocket.