preface

With regard to computer networks, the main part is communication, and according to the mode of communication, we can divide protocols into three categories: singlepower, half duplex, duplex; HTTP protocol is one of the most common communication protocols. How do you tell the difference? We divide the communication ends into client and serve ends. If only one-way transmission, such as C -> S, it is single work. For example, one end can respond to the request, but can not actively send information, that is half double work; Second, both ends can actively push, that is double work, our protagonist websocket today is a double work protocol.

What problem does it solve?

Before websocket, there are three solutions for the situation that the server has continuous state changes and the client needs to know about them

  • Polling (Polling) : The client periodically initiates a request state and has high pressure
    • Ordinary polling
    • Long polling (long-polling)
  • Iframe Streaming: A client does not close requests all the time
  • EventSource streams: cannot cross domains

The details of these three solutions will be expanded at the end of this article, but you can also see that there are problems with the above three solutions, which is why WebSocket is widely used

How is it used?

serve.js
let express = require('express');

let app = express();
app.use(express.static(__dirname));


let WebSockerServer = require('ws').Server;
let server = new WebSockerServer({
    port: 8888
})
// socket indicates the socket
server.on('connection'.function (socket){
    console.log('2. The server is listening to the client connection ');
    socket.on('message'.function (message){
        console.log(4. Client Connection Information, message);
        socket.send(5. The server says:+message)
    })
})

app.listen(3001)
Copy the code
client

The script in index.html

let socket = new WebSocket('ws://localhost:8888');
socket.onopen = function () {
  console.log('1. The client is connected to the server ');
  socket.send('3. How are you')
}
socket.onmessage = function (event) {
  console.log('6. + event.data);
}
Copy the code
The phenomenon of

The characteristics of

Exists on the request when the upgrade protocol is initiated

  • Request header
    • Connection : Upgrade
    • Upgrade : websocket
    • Sec-websocket-version: [WebSocket Version number]
    • Sec-websocket-key: [base64 encryption Key]{and in the response headerSec-WebSocket-AcceptIf the match is successful, the ws protocol will be upgraded.
    • Exists on the response
  • The status code is 101 switching Protocols successful
  • Response headers
    • Connection: Upgrade (Http common keep-alive)
    • Upgrade : websocket

There are three solutions before websocket

polling

Normal polling: Basically, you start a timer and keep making requests

let clock = document.querySelector('#clock');
        setInterval(function (){
            let xhr = new XMLHttpRequest;
            xhr.open('GET'.'/clock'.true);
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    clock.innerHTML = xhr.responseText;
                }
            }
            xhr.send()
        },1000)
Copy the code

Long polling: Differs from normal polling in that the next request is postpended after the previous response

function send() {
            let xhr = new XMLHttpRequest;
            xhr.open('GET'.'/clock'.true);
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    clock.innerHTML = xhr.responseText;
                    send()
                }
            }
            xhr.send()
        }
        send()
Copy the code

The problem is also obvious, the client will make a lot of meaningless requests

iframe

The IFrame scheme is a bit like JSONP, and the key to this implementation is two things

  • Iframe displays the contents returned by SRC in the iframe (so that a script can be returned for manipulation)
  • The server writes out the data after receiving the iframe request but keeps opening the connection so that new data can be written out as the data changes

Client

 <! SRC will be requested by default and the result will be returned in iframe.
    <iframe src="/clock" frameborder="0"></iframe>

    <script>
        function setTime(ts) {
            document.querySelector('#clock').innerHTML = ts;
        }
    </script>
Copy the code

serve

let express = require('express');

let app = express();
app.use(express.static(__dirname));
app.get('/clock'.function (req,res){
    res.header('Content-Type'.'text/html');
    setInterval(function (){
        res.write(`
            <script>
                parent.setTime("The ${new Date().toLocaleString()}")
            </script>
        `)
    })
})

app.listen(8000)
Copy the code

The problem is that the client is always in the request state, so the TAB bar keeps going around and around

EventSource flow

EventSource is an API from the standard library, W3C: EventSource

Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is standardized as part of HTML5[1] by the W3C. SSE is a technology that enables browsers to automatically receive server-side updates over HTTP connections. The SSE EventSource interface was developed by W3C as part of HTML5.Copy the code

client

let eventSource = new EventSource('/clock');
// Listen for messages from the server
eventSource.onmessage = function (event) {

  console.log('onmessage',event);
  let message = event.data;
  clock.innerHTML = message;
}
eventSource.onerror = function (event) {}Copy the code

server

The key is three things

  1. Content-TypeSet totext/event-stream
  2. In accordance with theevent:messageWrite the data
  3. Write out the data\r\nAt the end
res.header('Content-Type'.'text/event-stream');
setInterval(function (){
  // res.write(`  
  // event:message
  / / `)
  res.write(`
event:message\ndata:The ${new Date().toLocaleString()}\r\n
`)},1000)
Copy the code

Disadvantages:

  1. Can’t cross domain
  2. Only the server can be pushed to the client
WebSocket vs. EventSource
  1. WebSocket is TCP based, and EventSource is HTTP based.
  2. EventSource is one-way communication, while Websocket is two-way communication.
  3. EventSource can only send text, while WebSocket supports sending binary data.
  4. EventSource is simpler to implement than Websocket.
  5. EventSource has the ability to automatically reconnect (without third parties) and send random events.
  6. Websocket is too heavy and EventSource is lighter.
  7. Websocket can be cross-domain, and cross-domain EventSource over HTTP requires the server to set the request header.

At the end of the article recommended

Ruan Yifeng teacher Websocket