Websocket is a persistent network communication protocol that can carry out full-duplex communication on a single TCP connection. Without the concept of Request and Response, the two are completely equal, allowing the server to actively send data to the client. Once the connection is established, Two-way data can be transmitted between the client and server in real time.

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.

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

(2) “No source restriction”, the client can communicate with any server.

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

The client

Since Websockets are initially provided in HTML5, clients can create NEW WS objects for establishing communication.

let ws = new WebSocket('ws://localhost:3000');

ws.onopen = (a)= > {
    console.log('open connection');
}
 ws.onmessage = (event) = > {  // The client receives a callback from the server  console.log(event,'onmessage event'); }  ws.onclose = (a)= > {  console.log('close connection') }  Copy the code

These are the three websocket events, and one is an error event, which is obviously raised when communication fails.

There are also two common websocket methods that we’ll use in future examples:

ws.send();  // Use the connection to send data
ws.close();  // Close the connection
Copy the code

The service side

In Node, the most widely used websocket service is created through the WS module, which needs to be installed before using:

const express = require('express');

const SocketServer = require('ws').Server;

const port = 3000;
 const server = express().listen(port, () => {  console.log(`listening to ${port}`); })  const wss = new SocketServer({server});  wss.on('connection', (ws) => {  console.log('Client connected.');   ws.on('message', (data) => {  console.log(data);  // The server sends data to the client  ws.send(data);  })   ws.on('close', () = > { console.log('Close connected.')  }) }) Copy the code

To start the service, run:

node server.js
Copy the code

You can see the service start:

listening to 3000

When you visit the client page, you can see:

open connection

Type WS and press Enter to display the ws object information:

WebSocket{
    binaryType: "blob"
    bufferedAmount: 0
    extensions: ""
    onclose: (a)= > { console.log('close connection')} onerror: null  onmessage: (event) = > { console.log(event,'onmessage event'); }  onopen: (a)= > { console.log('open connection'); }  protocol: ""  readyState: 1  url: "ws://localhost:3000/" } Copy the code

There are four types of readyState that return the current state of the instance object:

state code meaning
CONNECTING 0 Indicates a connection.
OPEN 1 Indicates that the connection is successful and the communication is normal
CLOSING 2 Indicates that the connection is being closed
CLOSED 3 Indicates that the connection is closed or failed to open

Call send manually on the console to send the message:

ws.send('hello')
Copy the code

The send() method on the instance object is used to send data to the server, triggering the client ws. Onmessage event, and the server WS. On (‘message’) event is also triggered, and the server receives the message from the client.

The client prints the event message:


You can see the “Hello” message in the data property.

At the same time, the server can actively send messages to the client continuously:

wss.on('connection', (ws) => {
    console.log('Client connected.');
    const sendNowTime = setInterval((a)= > {
         ws.send(String(new Date()))
    },1000)
}); // The server sends real-time messages to the client every second Copy the code

After the client “connects”, it periodically receives data from the server until the connection or service is closed manually.

ws.close()

Simulated multiplayer chat

Here is a complete example to simulate a live websocket chat between two people:

Client code

<div id="app">
    <div class="box">
        <ul>
            <li v-for="(item,index) in news" :class="item.nickname == nickname ? 'me' : 'other'" :key="index">
                <img :src="item.nickname == nickname ? './static/me.jpg' : './static/other.jpg'" alt="">
 <p>{{item.message}}</p>  </li>  </ul>  <div>  <input type="text" v-model="send">  <button @click="sendMsg">send</button>  </div>  </div> </div> Copy the code
* {    margin: 0 ;
    padding: 0;
}
ul.li{
 list-style: none; } .box{  width: 500px;  margin: 0 auto; } .box ul li{  display: flex;   align-items: flex-start;  margin-bottom: 10px; } .box ul li img{  width: 40px;  height: 40px;  margin-right: 8px; } .box ul li p{  font-size: 14px;  line-height: 20px;  max-width: 300px;  background: #f1f1f1;  border-radius: 4px;  padding: 10px 20px; } .me{  justify-content: flex-start;  flex-direction: row; } .other{  flex-direction: row-reverse;  order:1 } Copy the code
let app = new Vue({
    el: '#app'.    data(){
        return {
            socketUrl: 'ws://localhost:8000? userName='. nickname: ' '. news: []. send: ' '. userList: []  }  },  mounted(){  this.initChatting();  let url = window.location.href;  this.nickname = url.split('=') [1]  },  methods: {  initChatting(){  if(window.WebSocket){  this.client = new WebSocket(this.socketUrl + this.nickname);   this.client.onopen = (e) = > {  if(e.type == 'open') { console.log('Client connection')  }  }  // The client receives a callback from the server  this.client.onmessage = (e) = > {  let data = JSON.parse(e.data);  if(data instanceof Array= =true) { this.userList = data; // The number of online users changes  }else{  // Chat messages  this.news.push(data);  }  console.log(this.news)  }  this.client.onclose = (e) = > {  this.client = null;  }  this.client.onerror = (a)= > {  if(!this.client){  console.log("Service connection failed")  }  }  }else{  alert("Browser version too old to support Websocket.")  }  },  sendMsg(){  let data = {  message: this.send,  uid: new Date().getTime(),  nickname: this.nickname,  date: new Date(a) }  this.client.send(JSON.stringify(data))  this.send = "";  }  } }) Copy the code

Server code

const WebSocket = require('ws').Server;
const moment = require('moment');
const url = require('url');
const querystring = require('querystring');

let wss = new WebSocket({  url: 'localhost'. port: 8000 })  let id = 0; let onlineMemberList = []; let defaultUser = 'user';  wss.on('connection', (ws,req) => {  console.log('connected.')  id++;  ws.id = id;  let arg = url.parse(req.url).query;  let nameObj = querystring.parse(arg);  let userName;  if(nameObj.username){  userName = decodeURIComponent(username);  }else{  userName = defaultUser + id  }   let userInfo = {  userName,  socketId: id,  date: moment().format('MMMM Do YYYY, hh:mm:ss a')  }   for(let i=0; i<onlineMemberList.length; i++){ if(userInfo.userName === onlineMemberList[i].userName){  onlineMemberList[i] = userInfo;  wss.clients.forEach(item= > {  item.send(JSON.stringify(onlineMemberList))  })  return;  }  }  onlineMemberList.push(userInfo);  wss.clients.forEach(item= > {  item.send(JSON.stringify(onlineMemberList));  })  ws.on('message',(data) => {  let newData = JSON.parse(data);  console.log(data,'data')  newData.serveDate = moment().format('MMMM Do YYYY, h:mm:ss a');  wss.clients.forEach(item= > {  // Listen to the data sent by the client, directly return the message intact, all back  item.send(JSON.stringify(newData));  })  })   ws.on('close',(e) => {  onlineMemberList = onlineMemberList.filter(item= > {  returnitem.socketId ! = ws.id; })  wss.clients.forEach(item= > {  item.send(JSON.stringify(onlineMemberList));  })  })  ws.on('error',(e) => {  console.log('Client exception',e)  }) }) Copy the code

Implementation effect


Send and receive messages across domains

Since Websocket can establish point-to-point links between client and service endpoints, it is not affected by cross-domain problems and can also be used to solve client cross-domain problems:

let ws = new WebSocket("ws://localhost:8200"); // Establish a connection
ws.onopen = function () { // Open the protocol
    console.log("Connection successful");
}
ws.onmessage = function (mes) { // Send data to the server
 console.log(mes); } // ws.addEventListener("message", function (e) {});  document.querySelector(".btn").onclick = function () {  let input = document.querySelector(".input").value;  console.log("Message sent from client to server:" + input);  ws.send(input); Ws.close () : the WebSocket is already in CLOSING or CLOSED state. }; Copy the code

After reading this article, I hope readers can have a preliminary understanding of Websocket, and can use it faster in work and practice.

This article is formatted using MDNICE