Probe into the principle of websocket

Source: Internet
Author: User

This article outlines

The goal of WEB sockets is to provide full-duplex, bidirectional communication on a single persistent connection. After JavaScript creates a Web socket, an HTTP request is sent to the browser to initiate the connection. After the server response is obtained, the connection is switched from the HTTP protocol to the WebSocket protocol for the HTTP upgrade.
Because WebSocket uses a custom protocol, the URL pattern is slightly different. Unencrypted connections are no longer http://, but ws://; encrypted connections are not https://, but wss://. This pattern must be used when using the WebSocket URL, as it is possible to support other schemas in the future.
The advantage of using a custom protocol instead of the HTTP protocol is the ability to send very small amounts of data between the client and the server without worrying about byte-level overhead at HTTP. Because the packets passed are small, WebSocket is ideal for mobile applications.
The above is just a general description of the Web sockets, the next space will be the details of the implementation of the Web sockets in-depth exploration, this article will not involve a lot of code snippets, but will be related to the API and technical principles of analysis, I believe you read the following after reading this paragraph of the description, There will be an enlightened feeling.

First, websocket the Handshake channel of the HTTP

A handshake channel is a connection channel that is established by the client and server in the HTTP protocol through the TCP three-time handshake. Each interaction between the client and the server using the HTTP protocol requires establishing such a "channel" and then communicating through this channel. The familiar Ajax interaction is to complete the data transfer on such a channel, the following is the process of establishing a "handshake channel" in the HTTP protocol:

As we mentioned above, after JavaScript creates the WebSocket, an HTTP request is sent to the browser to initiate the connection, and then the server responds, which is the "handshake" process, in which the client and the server do two things:

    1. A connection "handshake channel" is established for communication (this is the same as the HTTP protocol, unlike the HTTP protocol, which releases the handshake channel after the data interaction has been completed, which is called a "short connection" whose life cycle is the time of the data interaction, usually at the millisecond level.) )
    2. A persistent connection is established by upgrading the HTTP protocol to the WEBSOCKET protocol and reusing the Handshake Channel of the HTTP protocol.

      In this case, one might ask: Why does the HTTP protocol not use its own "handshake channel" instead of having to re-establish a "handshake channel" over a TCP three handshake every time the data interacts? The answer is this: while "Long connect" eliminates the hassle of creating a "handshake channel" each time the client and server interact, maintaining such a "long connection" consumes the resources of the servers, and in most cases, the consumption of such resources is unnecessary. It can be said that the development of HTTP standards has been carefully considered. Come back to us. When you talk about WebSocket protocol data frames, you might understand that there are too many things to do to maintain a "persistent connection" server and client.

      After talking about the handshake channel, let's see how the HTTP protocol is upgraded to the WebSocket protocol.

Second, HTTP protocol upgrade to WebSocket protocol

升级协议需要客户端和服务端交流,服务端怎么知道要将HTTP协议升级到WebSocket协议呢?它一定是接收到了客户端发送过来的某种信号。下面是我从谷歌浏览器中截取的“客户端发起协议升级请求的报文”,通过分析这段报文,我们能够得到有关WebSocket中协议升级的更多细节。

首先,客户端发起协议升级请求。采用的是标准的HTTP报文格式,且只支持GET方法。下面是重点请求的首部的意义:
    1. Connection:upgrade: Represents the protocol to be upgraded
    2. Upgrade:websocket: Indicates that you want to upgrade to the WebSocket protocol
    3. Sec-websocket-version:13: The version that represents WebSocket
    4. sec-websocket-key:udtuf90cc561cqxn4n5xrg==: The response header in the response header sec-websocket-accept: Gzk41fjzsyy0cmsrzpgpugrqzky= is a companion that provides basic protection, such as a malicious connection or unintentional connection.

      Where connection is what we mentioned earlier, the client sends the signal to the server, and the server receives the signal before the HTTP protocol is upgraded. So how does the server confirm that the request sent by the client is legitimate? A unique code is generated each time the client initiates a protocol upgrade request: Sec-websocket-key. After the server has got this code, through an algorithm to verify, and then through the sec-websocket-accept response to the client, the client and then verify the sec-websocket-accept to complete the verification. The algorithm is simple:

1. Identify the sec-websocket-key with the globally unique (guid,[rfc4122]): 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 stitching

2. Calculate the digest by SHA1 and turn it into a base64 string

258eafa5-e914-47da-95ca-c5ab0dc85b11 This string is also called "Magic string", as to why to use it as a websocket handshake calculation used in the string, we do not need to care, just need to know that it is the RFC standard provisions on it, The official analysis is simply saying that this value is unlikely to be used by network terminals that do not understand the WebSocket protocol. We still use the best language in the world to describe this algorithm.

public function dohandshake($sock, $data, $key) {        if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $data, $match)) {            $response = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));            $upgrade  = "HTTP/1.1 101 Switching Protocol\r\n" .                "Upgrade: websocket\r\n" .                "Connection: Upgrade\r\n" .                "Sec-WebSocket-Accept: " . $response . "\r\n\r\n";            socket_write($sock, $upgrade, strlen($upgrade));            $this->isHand[$key] = true;        }    }
服务端响应客户端的头部信息和HTTP协议的格式是相同的,所以这里Sec-WebSocket-Accept字段后边的两个换行符是少不了的,这和我们使用curl工具模拟get请求是一个道理。这样展示结果似乎不太直观,我们使用命令行CLI来根据中的Sec-WebSocket-Key和握手算法来计算一下服务端返回的Sec-WebSocket-Accept是否正确:

As you can see, the Base64 string calculated by the algorithm is the same as the sec-websocket-accept. What happens if the server returns an incorrect sec-websocket-accept string during the handshake? Of course, the client will error, the connection will build failure, we'd better try, For example, change the globally unique identifier 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 to 258EAFA5-E914-47DA-95CA-C5AB0DC85B12.

Third, websocket data frame

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.