webSocket and ajax, webSocket API, webSocket principle, socket io, chat room

Author: Wang Jiaojiao

When: August 2, 2017

Let's take a look at a reasonable explanation:

In fact, the interpretation is quite vivid, let me explain it one by one:

1. Chat room: The famous application of webSocket is the chat room;

2. Service: webSocket provides the server and service requested by the client;

3. Socket: The combination of source IP address and destination IP address as well as source port number and destination port number is called socket, and webSocket is the combination of server and client;

4. Protocol: webSocket is a new network protocol based on TCP.

1. webSocket and ajax

As a front-end that has been coding for a long time, when it comes to webSocket, the first thing that flashes in my mind is of course ajax ajax ajax...what is ajax, when ajax first came out, it was a sensation, let us say goodbye happily To submit a form, you must fill in all the information, and then transfer the data to the server for verification. It turns out that there is a small input box with wrong information, and then change the painful era of resubmitting and walking the same road. , so its biggest contribution is local refresh. Of course, it does not mean that with webSocket, it is out, and ajax is still easy to use. The following is a slight comparison of ajax and webSocket:

1、ajax

(1) The browser actively sends a message to the server;

(2) Non-real-time data interaction (asynchronous, partial refresh).

Native writing:

Four steps: ajax object, establish connection, send request, get corresponding .

A more popular analogy is to use a phone call, that is: call, dial, speak, and hear the other party's response . demo

//创建一个ajax对象(想打电话,首先得有电话这个对象)
var XHR = null;  
if (window.XMLHttpRequest) {  
    // 非IE内核  
    XHR = new XMLHttpRequest();  
} else if (window.ActiveXObject) {  
    // IE内核,早期IE的版本写法不同
    XHR = new ActiveXObject("Microsoft.XMLHTTP");  
} else {  
    XHR = null;  
}  
  
if(XHR){  
    //建立连接(拨号)
    XHR.open("GET", "ajaxServer.action");  

    //发送请求(说话)
    XHR.send();  
    
    //获取响应(听到对方回应)
    XHR.onreadystatechange = function () {  
        // readyState值说明  
        // 0,初始化,XHR对象已经创建,还未执行open  
        // 1,载入,已经调用open方法,但是还没发送请求  
        // 2,载入完成,请求已经发送完成  
        // 3,交互,可以接收到部分数据  
  
        // status值说明  
        // 200:成功  
        // 404:没有发现文件、查询或URl  
        // 500:服务器产生内部错误  
        if (XHR.readyState == 4 && XHR.status == 200) {  
            // 这里可以对返回的内容做处理  
            // 一般会返回JSON或XML数据格式  
            console.log(XHR.responseText);  
            // 主动释放,JS本身也会回收的  
            XHR = null;  
        }  
    };  
}

JQuery writing (so easy, my mother no longer has to worry about my learning):

$.ajax({
    type:"post",
    url:url,
    async:true,
    data:params,
    dataType:"json",
    success:function(res){
        console.log(res);
    },
    error:function(jqXHQ){
        alert("发生错误:"+jqXHQ.status);
    }
});

 

2、webSocket

(1) Full-duplex communication between the browser and the server is realized - allowing the server to actively send information to the client;

(2) Real-time data interaction.

// Create WebSocket connection.
var socket = new WebSocket('ws://localhost:8080');    //创建一个webSocket实例

// Connection opened
socket.addEventListener('open', function (event) {   //一旦服务端响应WebSocket连接请求,就会触发open事件
    socket.send('Hello Server!');
});

// Listen for messages
socket.addEventListener('message', function (event) {  //当消息被接受会触发消息事件
    console.log('Message from server', event.data);
});

 

WebSocket API

Since a part of the code is written above, it is better to post all the APIs, hahaha.

First, create a webSocket instance:

var socket = new WebSocket('ws://localhost:8080');  

Then look at the API below.

1. Events

(1)open

An event listener for connection open events. This event is fired when readyStatethe value becomes OPEN. This event indicates that the connection is ready to accept and send data. This listener will accept an event object named "open".

socket.onopen = function(e) {
    console.log("Connection open...");
};

or:

socket.addEventListener('open', function (event) {
    console.log("Connection open...");
});

(2)message

An event listener for message events that fire when a message arrives. The Listener will be passed an  MessageEvent object called "message".

socket.onmessage = function(e) {
   console.log("message received", e, e.data);
};

(3)error

An event listener to listen for the error event when an error occurs. Will accept an event object named "error".

socket.onerror = function(e) {
   console.log("WebSocket Error: " , e);
};

(4)close

A listener for listening for connection close events. This event is fired when the readyState of the WebSocket object changes to CLOSED. This listener will receive an  CloseEvent object called close.

socket.onclose = function(e) {
   console.log("Connection closed", e);
};

 

2. Method

(1)send

Send data to the server over a WebSocket connection.

Once a full-duplex two-way connection is established between the server and the client, the send method can be used to send messages. When the connection is open, the send() method transmits data, and when the connection is closed or cannot be obtained, an exception is thrown .

A common mistake is that people like to send a message before the connection is open. As follows:

// 这将不会工作
var socket= new WebSocket("ws://localhost:8080")
socket.send("Initial data");

You should wait for the open event to trigger before sending the message. The correct posture is as follows:

var socket= new WebSocket("ws://localhost:8080")
   socket.onopen = function(e) {
   socket.send("Initial data");
}

(2)close

Close the WebSocket connection or stop an ongoing connection request. If the state of the connection is already closed, this method has no effect.

Use the close method to close the connection. If the connection is closed, this method will do nothing. After calling the close method only, the data will not be sent. The close method can pass in two optional parameters, code (numerical) and reason (string), to tell the server why the connection is terminated.

socket.close(1000, "Closing normally");
//1000是状态码,代表正常结束。

 

3. Properties

property name Types of describe
binaryType DOMString

A string representing the type of binary content being transmitted. The value should be "blob" or "arraybuffer".

"blob" means using DOM Blob objects, and "arraybuffer" means using  ArrayBuffer objects.

bufferedAmount unsigned long The method was called  send() to queue multibyte data for transmission, but not yet issued. The value is reset to 0 after all queue data has been sent. It will not be set to 0 when the connection is closed. If called continuously send(), this value will continue to grow. Read only .
extensions DOMString Server selected extensions. Currently this property is just an empty string, or a list containing all extensions.
protocol DOMString A string indicating the name of the subprotocol selected by the server. The value of this property will be taken as the protocols parameter passed in by the constructor.
readyState unsigned short The current state of the connection. The value is  one of the Ready state constants . Read only .
url DOMString The URL passed into the constructor. It must be an absolute URL. Read only .

 

4. Constants

Ready state constant

constant value describe
CONNECTING 0 The connection has not been opened yet.
OPEN 1 The connection is open and ready to communicate.
CLOSING 2 The connection is in the process of being closed.
CLOSED 3 The connection has been closed, or the connection could not be established.

 

3. webSocket and HTTP

Both webSocket and http are protocols. Everyone must think about the connection between them. Of course, I am also curious, so I have the following research results, hehehe~~

As we all know, webSocket is a new protocol of H5 (it seems that it has nothing to do with http). The essence is to create a TCP connection for exchanging data after handshake through the http/https protocol. TCP connection for real-time communication. That is to say, webSocket is a supplement to the http protocol.

Compared with HTTP, which is a non-persistent protocol, Websocket is a persistent protocol.

Take the life cycle of php as an example:

In http1.0, one request, one response, one cycle is over.

In http1.1, with keep-alive, you can send multiple Requests and receive multiple Responses. But in http, it is always a request corresponding to a response. And this response is passive and cannot be initiated actively.

This is where webSockets come in handy.

 

Fourth, the principle of webSocket

First, let's take a look at an http Request Headers:

Look at another webSocket:

And the Response Headers of webSocket:

I guess, whether you are familiar with http or not, you must have seen the difference, hahaha. Next we will explain these things:

(1)Upgrade和Connection

Upgrade: websocket
Connection: Upgrade

This is the core of webSocket, telling Apache, ngix and other servers: Attention, I initiated the webSocket protocol, quickly help me find the corresponding assistant to handle ~ not the old-fashioned http.

(2)Sec-WebSocket-Key、Sec-WebSocket-Extensions和Sec-WebSocket-Version

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Extensions: chat, superchat
Sec-WebSocket-Version: 13

This is easy to understand. First of all, Sec-WebSocket-Key is a Base64 encoded value, which is randomly generated by the browser and tells the server: Hello, I am webSocket, this is my ID card, let me go.

Then, Sec-WebSocket-Extensions : Protocol extensions, a certain type of protocol may support multiple extensions, through which protocol enhancements can be achieved

Finally, Sec-WebSocket-Version tells the server what webSocket Draft (protocol version) to use. Well, I am Doraemon version 4.1 of Xiaomao, hahahahahahaha.

Then as long as the server returns the series of balabala things I put above, it means that the request has been accepted, and the webSocket is established successfully!

(3)Sec-WebSocket-Accept和Sec-WebSocket-Extensions

When requesting, webSocket will bring its own encrypted ID card to the server for verification;

Correspondingly, after accepting the request, the server must also get a security card (the value of the Accept header field is the value of the Key, which is generated by the Sec-WebSocket-Key sent by the browser) to prove that I agree with you. Not some bad silver that can be kidnapped ->

In this way, the principle part is finished, the handshake is successful!

 

Five, the role of webSocket

Before talking about webSocket, let's talk about ajax polling and long poll.

1. Ajax polling:

Ajax polling is very simple, it is to let the browser send a request every few seconds to ask the server if there is new information.

客户端:hello hello,有没有新信息(Request)

服务端:没有(Response)

客户端:hello hello,有没有新信息(Request)

服务端:没有。。(Response)

客户端:hello hello,有没有新信息(Request)

服务端:你好烦啊,没有啊。。(Response)

客户端:hello hello,有没有新消息(Request)

服务端:有啦有啦,here you are(Response)

客户端:hello hello,有没有新消息(Request)

服务端:。。没。。。。没。。。没。。。。(Response)

 

2、long poll

The principle of long poll and ajax polling is very similar, but long poll is a blocking model. In short, it keeps calling you until you answer.

客户端:hello hello,有没有新信息,没有的话就等有了再返回给我吧(Request)

服务端:额。。。     (。。。。等待到有消息的时候。。。。)     有了,给你(Response)

Obviously, ajax polling and long poll do more harm than good:

(1) Passivity

The above two methods are that the client first sends a message to the server, and then waits for the server to respond. You must know that waiting is always difficult. If the server can send messages actively, this is one of the disadvantages: passivity .

(2) Very resource-intensive

Ajax polling requires the server to have fast processing speed and resources (speed);

Long poll requires high concurrency, that is, the ability to receive customers at the same time (site size).

so, when ajax polling and long poll hit 503 (aaaaaah, game over)

At this time, the magical webSocket comes in handy again.

 

3、webSocket

(1) Passivity

First, address passivity:

客户端:hello hello,我要建立webSocket协议,扩展服务:chat,Websocket,协议版本:17(HTTP Request)

服务端:ok,确认,已升级为webSocket协议(HTTP Protocols Switched)

客户端:麻烦你有信息的时候推送给我噢。。

服务端:ok,有的时候会告诉你的。

服务端:balabalabalabala

服务端:balabalabalabala

服务端:哈哈哈哈哈啊哈哈哈哈

服务端:笑死我了哈哈哈哈哈哈哈

In this way, only one http request is needed, and there will be a steady stream of information transmission, isn't it very convenient.

(2) The problem of resource consumption

First of all, let's understand that the program we use goes through two layers of proxies, that is, the http protocol is parsed by servers such as Nginx, and then sent to the corresponding Handler (PHP, etc.) for processing. Simply put, we have a very fast operator (Nginx) who is responsible for passing the problem to the corresponding customer service (Handler).

The operator itself is basically fast enough, but it gets stuck in the customer service (Handler) every time. The processing speed of the old customer service is too slow, resulting in insufficient customer service.

webSocket solves such a problem. After establishment, a persistent connection can be established directly with the operator. When there is information, the customer service will find a way to notify the operator, and then the operator will transfer it to the customer.

This can solve the problem that the customer service processing speed is too slow.

At the same time, in the traditional way, it is necessary to continuously establish and close the HTTP protocol. Since HTTP is non-state, the authentication information must be retransmitted every time to tell the server who you are.

Although the operator is very fast, but every time they have to listen to such a bunch of them, the efficiency will also decrease. At the same time, they have to constantly transfer these information to the customer service, which not only wastes the processing time of the customer service, but also consumes the network transmission. Excessive traffic/time.

But webSocket only needs one http handshake, so the entire communication process is established in one connection/state, which avoids the non-state nature of http, and the server will always know your information until you close the request, which is solved The operator has to repeatedly parse the http protocol and check the information of the identity info.

 

6. Socket.io

Since it comes to webSocket, it is inevitable to mention socket.io.

Some people say that socket.io is the encapsulation of webSocket and implements the server-side code of webSocket. It can be said, but not entirely correct.

Before the advent of webSocket, real-time communication with the server could be done by polling. Socket.io encapsulates webSocket and polling (Polling) mechanisms and other real-time communication methods into common interfaces, and implements the corresponding codes of these real-time mechanisms on the server side. That said, webSocket is just a subset of what Socket.io implements for real-time communication.

Let's go directly to a small chat room made with socket.io.

(1) First you have to have node, and then install socket.io.

$ npm install socket.io

(2) Server side (index.js)

'use strict';
module.exports = require('./lib/express');

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

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

io.on('connection', function(socket){
    socket.on('message',function(msg){
        console.log(msg);
        socket.broadcast.emit('chat',msg);    //广播消息
    })
});

http.listen(3000);

(3) Client

First import the js file:

<script src="/socket.io/socket.io.js"></script>

Interactive code (index.html):

<!DOCTYPE html><html><head>
<meta charset="UTF-8">
<title>聊天室</title>
<style>
body,div,ul,li{margin: 0;padding: 0;list-style: none;}
.auto{margin: auto;}
.l{text-align: left;}
.r{text-align: right;}
.flex{display: box;display: -webkit-box;display: -moz-box;display: -ms-flexbox;display: -webkit-flex;display: flex;-webkit-box-pack: center;-webkit-justify-content: center;-moz-justify-content: center;-ms-justify-content: center;-o-justify-content: center;justify-content: center;-webkit-box-align: center;-webkit-align-items: center;-moz-align-items: center;-ms-align-items: center;-o-align-items: center;align-items: center;}
.chat-box{background: #f1f1f1;width: 56vw;padding:2vw;height:36vw;border:1px solid #ccc;margin-top: 2vw;}
.chat-li{display:inline-block;margin-top: 5px;background: #5CB85C;border-radius: 5px;padding: 3px 10px;color: #fff;}
.other-chat-li{background: #fff;color: #333;}
.send-box{width: 60vw;border:1px solid #ccc;justify-content: space-between;border-top: 0;}
.send-text{width: 50vw; border: none; padding: 10px;outline:0;}
.send{width: 10vw;background: #5cb85c; border: none; padding: 10px;color: #fff;cursor: pointer;}
.chat-name{color: #f00;}
.other-box,.self-box{width: 50%;height:100%;}
</style>
</head>
<body>
    <div class="chat-box auto flex">
        <ul class="other-box l"></ul>
        <ul class="self-box r"></ul>
    </div>
    <div class="flex send-box auto">
        <input class="send-text" type="text">
        <button class="send" type="button">发送</button>
    </div>
</body>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
    $(function(){  
        var socket = io();
        
        $(".send").click(function(){
            var msg = $(".send-text").val();
            if(msg != ""){
                socket.send(msg);
                $('.self-box').append('<li class="chat-li">'+ msg +'<li>');
                $(".send-text").val("");
            }else{
                return false;
            }
        })
        
        $(".send-text").keydown(function(event){
            if(event.keyCode == 13){
                var msg = $(".send-text").val();
                if(msg != ""){
                    socket.send(msg);
                    $('.self-box').append('<li class="chat-li">'+ msg +'<li>');
                    $(".send-text").val("");
                }else{
                    return false;
                }
            }
        })

        socket.on("chat",function(msg){
            $('.other-box').append('<li class="other-chat-li chat-li">'+ msg +'<li>');
        })
    })
</script>
</html>

(4) Run the code:

$ node index.js

Then open two browser pages ( http://localhost:3000/ ), you can chat, as for the chat name, chat avatar, etc., you can research Luo~~~

The following is the effect diagram:

It's over, it feels like a foot wrap, so long~~~~~~~~~

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326078534&siteId=291194637