Hello everyone, I'm Xiao Cai~

This article mainly introduces Socket.IO

The WeChat public account has been opened, , students who didn't follow it remember to pay attention!

Before introducing Socket.IO , let's consider a question. If there is a demand at this time, how to implement the function similar to the realization of manual customer service?
image

Online customer service, the requirements are very simple to understand, it is equivalent to a web chat page, that is, the client can the response from the server

Of course, as an interface engineer, this is not a difficult problem to solve. We can provide an interface for obtaining chat records, through which we can obtain

The other party has already sent a message. Then the question comes again, how to ensure that get the chat history in real time? Presumably this is not a problem, the front end can pass the timer

In this way, the interval time is shortened to 100 milliseconds, so that the near real-time message acquisition has been achieved.

setInterval(function () { 
    // do something
},100)

When we finished writing the above code and went online, we can find through monitoring that the server indicators after went online are significantly improved than before

The server is a very precious resource, so why does this happen? In retrospect, it is understandable that this happened, and a request is made every 100 milliseconds.

Secondary backend, if there are chat records generated, then this kind of request is considered meaningful, but if there is no chat for a long time, each request returns an empty record, then this kind of

Frequent requests are meaningless. Frequent requests stress the server and waste bandwidth traffic.

So is there any other way to solve it?

We may be able to use the SSE method, SSE not a relatively new concept, and it appeared very early

The full name of SSE is Server-Sent Events, which refers to the automatic acquisition of updates from the server by the web page, that is, the automatic acquisition of the data pushed by the server to the web page. This is an H5 attribute. Except for IE, other standard browsers are basically compatible.

This method does not require the client to obtain it regularly, but the server declares to the client that it wants to send stream information, and then sends it continuously.


Although this method does not require regular polling, it can only communicate with . After the connection is established, it can only be sent from the server to the client, and one connection needs to be occupied. If the client needs to communicate with the server, then An additional connection needs to be opened!

What problems can be caused if there are too many connections?

The number of TCP connections is limited, SYN DDOS flood attack is to use the problem of TCP semi-connection to attack the server

so this is also not an elegant way to implement

In fact, here, our solution has been very clear, that is, how to let the server send the latest news to the client at the fastest of without wasting bandwidth.

The client. But obviously the HTTP protocol is not applicable, it will respond after the server receives the request. Therefore, in order to solve this problem, it is necessary to talk about

to a communication protocol, that is WebSocket

WebSocket is a computer communication protocol that provides a full-duplex communication channel over a single TCP connection.

To establish a WebSocket connection, the client will send a WebSocket handshake request, and the server will return a WebSocket handshake response for this, as follows

as shown in the figure.


Compared with the traditional HTTP mode in which each request-response requires the client to establish a connection with the server, is a of long connection

Set up a websocekt connection, unless one of the client or server actively disconnects, otherwise there is no need to request the number of HTTP requests before each data transfer.

according to

client requests

Upgrade: websocket
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
  • Upgrade is to indicate that this is a websocekt type request, which is intended to tell the server that the communication protocol needs to be switched to websocekt
  • Sec-WebSocket-Key is a base64-encoded cipher text sent by the client, asking the server to respond with a hash of the key in the Sec-WebSocket-Accept header. This is to prevent caching proxies from resending previous WebSocket conversations and does not provide any authentication, privacy or integrity.

    server response

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

The handshake starts with an HTTP request/response, allowing the server to handle HTTP connections and WebSocket connections on the same port. Once the connection is established, the communication is

Switch to a bidirectional binary protocol that does not conform to the HTTP protocol.

图源网, 侵删

In fact, the plan has come out here, but the title of our article is indeed Socket.IO , since we have Websocket, why are we talking about Socket.IO?

Socket.IO

Before you look down, let's clear this point:

Socket.IO is not replace , but to upgrade

Socket.IO is a library , we are all familiar with the library, the library encapsulates the existing functions, yes, it is built on the WebSocket protocol and provides additional guarantees, since it is Built on websocekt , indicating that it also has the function of delayed communication between client and server.

Socket.IO can be used to implement the following communication methods:

  • WebSocket Communication in HTML 5
  • WebSocket communication available in Flash
  • XHR polling
  • JSONP polling
  • Forever Iframe

Socket.IO ensures that both the client and the server can use the same API when implementing these communication methods. And has the following characteristics:

  • HTTP long polling fallback

If a WebSocket connection cannot be established, the connection will fall back to HTTP long polling.

  • auto-reconnect

Under some specific conditions, the WebSocket connection between the server and the client may be interrupted without both parties being aware of the disconnected state of the connection. And the reason Socket.IO includes a heartbeat mechanism that periodically checks the status of the connection. When the client finally disconnects, it automatically reconnects with an exponential fallback delay so as not to overwhelm the server

  • packet buffer

When the client disconnects, packets are automatically buffered and sent on reconnect

Since Socket.IO is so beautiful, how should it be used? Then let's create our own chat room !

This case is built in NodeJS environment, extremely simple, , you can try it if you have the conditions

chatroom

Prerequisites for preparation:

  • Make sure the Node.js environment is installed
  • prepare an empty folder

The preparation steps are very simple, then we start to create our own chat room

1. Create a package.json file

We create package.json file in an empty directory with the following contents:

{  
    "name": "c-chat",  
    "version": "0.0.1",  
    "description": "my first chat app",  
    "dependencies": {}
}

Execute the command npm install express in the current directory to install the web application development framework

2. Create index.js & index.html

Create index.js file in an empty directory, the content is as follows:

const app = require('express')();
const http = require('http').Server(app);

app.get('/', (req, res) => {
   res.sendFile(__dirname + '/index.html');
});

http.listen(port, () => {
   console.log(`${port} 端口监听成功`);
});

Then create index.html file with the following contents

<!DOCTYPE html>
<html>
 <head>
   <title>my chat</title>
   <style>
     body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

     #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
     #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
     #input:focus { outline: none; }
     #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }

     #messages { list-style-type: none; margin: 0; padding: 0; }
     #messages > li { padding: 0.5rem 1rem; }
     #messages > li:nth-child(odd) { background: #efefef; }
   </style>
 </head>
 <body>
   <ul id="messages"></ul>
   <form id="form" action="">
     <input id="input" /><button>Send</button>
   </form>
 </body>
</html>

In order to test whether the http service works with our page, we can use node index.js to start the project to verify
image

At this point, we have been able to successfully access our page, and then we will start to implement our chat function through socket.io

3. Install the socket.io library

npm install socket.io First, you need to execute the above command to install socket.io library

is now more than halfway to the goal

We only need to modify part of the content to see the effect we want

Server
const { Server } = require("socket.io");
const io = new Server(server);

The above code is to introduce the socket.io library and create a websocket service, and then you can establish socket monitoring

io.on('connection', (socket) => {console.log('连接建立成功');});

After a Socket.IO server is created, when the client establishes a connection with the server, the connection event of the Socket.IO server is triggered, which can be specified by listening to the event and specifying the event callback function. Processing to be performed when connecting

client

On the index.html page, we add the following code to import socket.io.js and create the socket object

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

So far that's all it takes to load socket.io-client , which exposes an io global (and the endpoint GET/socket.io/socket.io.js ), and then connect. We can restart the service, open the browser, and view the console results
image
It can be seen that the connection has been successfully established to . The next step is the most important part. Both parties need to send messages. Any object that can be encoded as JSON in IO can be sent, and binary data is also supported.

client

The code that needs to be modified in index.html is as follows:

<script>
  var socket = io();

  var messages = document.getElementById('messages');
  var form = document.getElementById('form');
  var input = document.getElementById('input');

  form.addEventListener('submit', function(e) {
    e.preventDefault();
    if (input.value) {
      socket.emit('chat message', input.value);
      input.value = '';
    }
  });

  socket.on('chat message', function(msg) {
    var item = document.createElement('li');
    item.textContent = msg;
    messages.appendChild(item);
    window.scrollTo(0, document.body.scrollHeight);
  });
</script>

You can send a message to the server through the emit method, where chat message is the destination address to send

In the emit method, use three parameters

socket.emit(event, data, callback)

  • The value of the event parameter is a string specifying the name of the event, which is the target topic
  • The data parameter value represents the data carried in the event, which will be received by the other party. The data can be a string or an object.
  • The value of the callback parameter is a parameter used to specify a callback function to be called when the other party confirms receipt of data
Server

The code that needs to be modified in the index.js file is as follows:

io.on('connection', (socket) => {
  socket.on('chat message', (msg) => {
    console.log('message: ' + msg);
  });
});

The target address is monitored by socket.on() , which is somewhat similar to the publish/subscribe model. Both parties subscribe to the same address, and then pass messages to this channel.
On the server side, we can also use the emit method to send messages to the client, and we can use socket.emit() to send messages

Attached: complete code

index.html

index.js

It's over here, come on guys, now restart the project, then open two browsers to localhost:3000 address and try talking to yourself!

Namespaces

Above we have simply implemented the function of a chat room, mainly using the following APIs

  • socket.on() Listen for events
  • socket.emit() message sending

These two are the most basic usages, let's talk about an extended usage, that is the namespace

If a developer wants to have complete control over the sending of messages and events in a specific application, it is sufficient to use a default namespace of "/" . But if the developer needs to provide the application as a third-party service to other applications, he needs to define a separate namespace for a socket port used to connect with the client.

In Socket.IO, use the of method of the Socket.IO server object to define the namespace, and the code is as follows (io in the code represents a Socket.IO server object).

io.of(namespace)

Let's see how to use it:

  • Server
io.of("/chat").on("connection", (socket) => {
  // 订阅对应的主题
  socket.on("chat message", (msg) => {
    console.log("message: " + msg);
    socket.emit("chat message", msg);
  });
});
  • client
var socket = io('http://localhost:3000/chats');

In the above example, we defined the chat to distinguish different socket connections. Friends can imagine what scenarios this can be applied to!

Summarize

SOCKET is a set of interfaces used to allow different computers and different processes to communicate with each other. Socket , the literal translation can be "socket", but it is often called "socket" in Chinese. To establish a connection, both parties will first apply for a socket to transmit messages

Don't talk empty-handed, don't be lazy, and be a programmer with who is bragging about X to do the architecture~ Just follow and be a companion, so that Xiaocai is no longer alone. See you below!

If you work harder today, tomorrow you will be able to say one less thing to ask for help!

I am Xiao Cai, a man who grows stronger with you. 💋

The WeChat public account has been opened, , students who didn't pay attention remember to pay attention!


写做
624 声望1.7k 粉丝