preface
Before this article, WebSocket many people have heard of, have not seen, have not used, thought is a very lofty technology, in fact, this technology is not mysterious, can be said to be a very easy to master the technology, I hope after reading this article, immediately put out the chestnut in the article to try their own, practice out of real knowledge.
Swimming, fitness know about: blog, front-end accumulation of documents, public number, GitHub
WebSocket
What problems have been solved:
The client (browser) can communicate with the server only when the client initiates ajax requests. The server cannot actively push information to the client.
When there are scenarios such as sports events, chat rooms, real-time locations, and so on, the client can only get changes on the server side by polling (timed requests) to see if there are new changes on the server side.
Polling is inefficient and wasteful of resources (constantly sending requests, constantly linking to the server)
The emergence of WebSocket, so that the server can take the initiative to send information to the client, so that the browser has real-time two-way communication ability, this isWebSocket
Problem solved
A super simple chestnut:
Create a newhtml
File, this chestnut to find a place to run to try, you can easily entryWebSocket
:
function socketConnect(url) {
// The client connects to the server
let ws = new WebSocket(url); // Returns the 'WebSocket' object, assigned to the variable ws
// Successful connection callback
ws.onopen = e= > {
console.log('Connection successful', e)
ws.send('I'm sending a message to the server'); // The client communicates with the server
}
// Listen for messages returned from the server
ws.onmessage = e= > {
console.log('Server side returns:', e.data)
// do something
}
return ws; // Returns the WebSocket object
}
let wsValue = socketConnect('ws: / / 121.40.165.18:8800'); / / the websocket object
Copy the code
The WebSocket interface address in the above mentioned from: WebSocket online test, in the development of time can also be used to test whether the address given by the back end is available.
WebSocket class:
When WebSocket is used in many parts of the project, it is better to seal it as a class.
The following chestnut, made very detailed comments, build an HTML file can also be directly used, websocket common API are put in.
The code noted below, however, refers to the heartbeat mechanism used to keep webSockets connected
class WebSocketClass {
/ * * *@description: initializes the instance attribute, saving the parameter *@param {String} Interface * for URL WS@param {Function} The msgCallback server information callback passes data to the function *@param {String} The name optional value is used to distinguish ws and is used for debugger */
constructor(url, msgCallback, name = 'default') {
this.url = url;
this.msgCallback = msgCallback;
this.name = name;
this.ws = null; / / the websocket object
this.status = null; // Whether webSocket is closed
}
/ * * *@description: Called * when initializing a webSocket connection or reconnecting to webSocket@param {*} Optional value Data to be transmitted */
connect(data) {
// Create a new WebSocket instance
this.ws = new WebSocket(this.url);
this.ws.onopen = e= > {
// The connection ws callback succeeded
this.status = 'open';
console.log(`The ${this.name}Connection successful ', e)
// this.heartCheck();
if(data ! = =undefined) {
// If there is data to be transmitted, send it to the backend
return this.ws.send(data); }}// Listen for messages returned from the server
this.ws.onmessage = e= > {
// Pass the data to the callback function and execute the callback
// if (e.data === 'pong') {
// this.pingPong = 'pong'; // Go back to pong on the server and modify the status of pingPong
// }
return this.msgCallback(e.data);
}
// ws closes the callback
this.ws.onclose = e= > {
this.closeHandle(e); // Determine whether to close
}
// ws error callback
this.onerror = e= > {
this.closeHandle(e); // Determine whether to close}}// heartCheck() {
// // The time of the heartbeat mechanism can be specified with the backend
// this.pingPong = 'ping'; // The heartbeat mechanism status of the ws
// this.pingInterval = setInterval(() => {
// if (this.ws.readyState === 1) {
// // Check ws for link status before sending
// this.ws.send('ping'); // 客户端发送ping
/ /}
/ /}, 10000)
// this.pongInterval = setInterval(() => {
// if (this.pingPong === 'ping') {
// this.closeHandle('pingPong is not changed to pong'); // No pong is returned and webSocket restarts
/ /}
// // reset to ping If the next ping fails to send or pong fails to return (pingPong will not be changed to pong), the system will restart
// console.log(' return pong')
// this.pingPong = 'ping'
/ /}, 20000)
// }
// Send information to the server
sendHandle(data) {
console.log(`The ${this.name}Sends a message to the server: ', data)
return this.ws.send(data);
}
closeHandle(e = 'err') {
// Since webSocket is unstable, you can only close it manually (call closeMyself) or reconnect it
if (this.status ! = ='close') {
console.log(`The ${this.name}Disconnect and reconnect to webSocket, e)
// if (this.pingInterval ! == undefined && this.pongInterval ! == undefined) {
// // Clear timer
// clearInterval(this.pingInterval);
// clearInterval(this.pongInterval);
// }
this.connect(); / / reconnection
} else {
console.log(`The ${this.name}Websocket is manually closed)}}// Disable WebSocket manually
closeMyself() {
console.log(Closed `The ${this.name}`)
this.status = 'close';
return this.ws.close(); }}function someFn(data) {
console.log('Callback for receiving server messages:', data);
}
// const wsValue = new WebSocketClass('ws://121.40.165.18:8800', someFn, 'wsName'); // This link can only send messages 50 times a day
const wsValue = new WebSocketClass('wss://echo.websocket.org', someFn, 'wsName'); // Ruan Yifeng tutorial link
wsValue.connect('Communicate with the server now'); // Connect to the server
// setTimeout(() => {
// wsvalue. sendHandle(' Send message to server ')
// }, 1000);
// setTimeout(() => {
// wsValue.closeMyself(); / / close the ws
// }, 10000)
Copy the code
You can put the class in a JS file,export it, and then import it where it needs to be used. You can use it by passing in the parameters.
WebSocket is not stable
WebSocket is unstable and may be disconnected after being used for a period of time. There seems to be no public opinion on why WebSocket is disconnected, so we need to keep WebSocket connected. Two methods are recommended here.
WebSocket sets the variable to determine whether to manually close the connection:
Set a variable to the webSocket closure/error callback to determine if it was closed manually, and reconnect if not. The advantages and disadvantages of this approach are as follows:
- Advantages: Fewer requests (compared to heartbeat connections), easy to set up.
- Disadvantages: May result in data loss. During disconnection and reconnection, the two parties are communicating.
WebSocket heartbeat mechanism:
Because of the disadvantages of the first scenario, there may be some other unknown situation that causes the connection to be disconnected without raising an Error or Close event. The result is that the actual connection has been disconnected, while the client and server are still waiting for the message.
Then the clever programming monkeys came up with a solution called the heartbeat mechanism:
The client is like a heartbeat that sends a ping at regular intervals to tell the server that I’m still alive, and the server is going to return Pong to tell the client that the server is still alive.
Specific implementation method, in the above class comment, open it, you can see the effect.
About the WebSocket
Afraid of the beginning of the pile too much text content, scared you away, now that you have been able to use, we go back to look at the other knowledge points of WebSocket.
The current state of WebSocket:WebSocket.readyState
Here are the four values for websocket. readyState (four states) :
- 0: the connection is ongoing
- 1: indicates that the connection is successful and the communication is normal
- 2: the connection is being closed
- 3: indicates that the connection is closed or fails to be opened
We can use the current state to do something like allow the client to ping only after the WebSocket connection is successful.
if (this.ws.readyState === 1) {
// check that ws is in a linked state before sending
this.ws.send('ping'); // The client sends ping
}
Copy the code
WebSocket
You can also send/receive binary data
Here I have not tried, I am to see ruan yifeng teacher’s WebSocket tutorial just know there is such a thing, interested can go to Google, we know it can.
Binary data includes blob objects and Arraybuffer objects, so we need to treat them separately.
// Receive data
ws.onmessage = function(event){
if(event.data instanceof ArrayBuffer) {// Determine the ArrayBuffer object
}
if(event.data instanceof Blob){
// Determine the Blob object}}// Send an example of Blob objects
let file = document.querySelector('input[type="file"]').files[0];
ws.send(file);
// Send an example of an ArrayBuffer object
var img = canvas_context.getImageData(0.0.400.320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
ws.send(binary.buffer);
Copy the code
If you want to send a large number of binary data, how to determine the completion:
The websocket. bufferedAmount property indicates how many bytes of binary data are not sent:
var data = new ArrayBuffer(10000000);
socket.send(data);
if (socket.bufferedAmount === 0) {
// Send complete
} else {
// Send is not finished yet
}
Copy the code
Above chestnut from ruan yifeng teacher’s WebSocket tutorial
Advantages of WebSocket:
One last wave of WebSocket:
-
Two-way communication (first and most important).
-
The data format is relatively light, with low performance overhead and high communication efficiency
Protocol-controlled packets have smaller headers, whereas HTTP requires complete headers for each communication
-
Better binary support
-
There are no same-origin restrictions, and clients can communicate with any server
-
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
conclusion
After reading this article, if you are still a little confused, be sure to put two of the text, a new HTML file to run, tinker with your own. Otherwise, it doesn’t matter how many blogs/tutorials you read. Real knowledge comes from practice.
I hope the friends can click like/follow, your support is the biggest encouragement to me.
Blog, front-end accumulation of documents, public number, GitHub
The above 2018.10.22
References:
WebSocket tutorial
Preliminary study and realization of Websocket heartbeat reconnection
WebSocket protocol: 5 minutes from beginner to master