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 header
Sec-WebSocket-Accept
If 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
Content-Type
Set totext/event-stream
- In accordance with the
event:message
Write the data - Write out the data
\r\n
At 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:
- Can’t cross domain
- Only the server can be pushed to the client
WebSocket vs. EventSource
- WebSocket is TCP based, and EventSource is HTTP based.
- EventSource is one-way communication, while Websocket is two-way communication.
- EventSource can only send text, while WebSocket supports sending binary data.
- EventSource is simpler to implement than Websocket.
- EventSource has the ability to automatically reconnect (without third parties) and send random events.
- Websocket is too heavy and EventSource is lighter.
- 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