How does Http Header determine if the protocol is Websocket

2021.05.10

introduction

First, to answer this question, http determines whether the current protocol should be upgraded to websocket by judging whether the header contains Connection: Upgrade and Upgrade: websocket. Let’s take a look at the WebSocket protocol and its origin.

The origin of WebSocket

Before WebSocket, if you need two-way communication between the client and the service, you need to implement it through HTTP polling. HTTP polling is divided into polling and long polling:



Among them, polling means that the browser starts a timer through JavaScript, and then sends a request to the server at a fixed interval to ask the server for new messages. Disadvantages:

Not enough real-time

Frequent requests will put great pressure on the server

Long polling means that when the browser sends a request, the server delays for a period of time and waits until there is a message before replying. This mechanism temporarily solves the real-time problem, but it brings new problems:

A server running in multi-threaded mode will cause most threads to be suspended most of the time, which greatly wastes server resources

When an HTTP connection has no data transmission for a long time, any gateway on the link may close the connection, and the gateway is out of our control

Therefore, HTML5 has added the WebSocket protocol, which can establish an unrestricted two-way communication channel between the browser and the server.

Why can WebSocket connection achieve full-duplex communication but HTTP connection can't?

In fact, the HTTP protocol is built on top of the TCP protocol. The TCP protocol itself implements full-duplex communication, but the request-response mechanism of the HTTP protocol restricts the full-duplex communication. After the WebSocket connection is established, it is actually just a simple stipulation: Next, we will not use the HTTP protocol for communication, and send data directly to each other.


Advantages of WebSocket:

Less control overhead: After the connection is created, when data is exchanged between the server and the client, the data packet header used for protocol control is relatively small

Stronger real-time performance: Since the protocol is full-duplex, the server can actively send data to the client at any time

Keep the connection state: Unlike HTTP, WebSocket needs to create a connection first, which makes it a stateful protocol, and then part of the state information can be omitted when communicating.

Better binary support: WebSocket defines binary frames, which can handle binary content more easily than HTTP

Can support extensions: WebSocket defines extensions, and users can extend the protocol and implement some custom sub-protocols


WebSocket protocol

WebSocket uses the Uniform Resource Identifier (URI) of ws or wss, where wss represents a WebSocket using TLS.

The ws:// data is not encrypted, and the data is visible to any intermediary.

wss:// is a WebSocket based on TLS, similar to HTTPS is HTTP based on TLS). The transport security layer encrypts the data at the sender and decrypts it at the receiver.

http determines whether it needs to be upgraded to the websocket protocol by judging whether the header contains Connection: Upgrade and Upgrade: websocket. In addition, there are other headers:



Sec-WebSocket-Key: a security key randomly generated by the browser

Sec-WebSocket-Version: WebSocket protocol version

Sec-WebSocket-Extensions: used to negotiate the WebSocket extensions to be used for this connection

Sec-WebSocket-Protocol: Protocol

When the server agrees to make a WebSocket connection, it returns a response code of 101.


Test address: https://www.websocket.org/echo.html

Once the socket is established, we should monitor events on the socket. There are 4 events in total:

open: the connection has been established

message: data received

error: WebSocket error

close: the connection has been closed

If we want to send a message, we can use socket.send(data)


let socket = new WebSocket("wss://echo.websocket.org")

socket.onopen = function(e) {

  console.log("[open] Connection established")

  // 发送消息

  socket.send("My name is an")

}

socket.onmessage = function(event) {

  console.log(`[message] Data received from server: ${event.data}`)

}

socket.onclose = function(event) {

  // ...

}

socket.onerror = function(error) {

  console.log(`[error] ${error.message}`)


to sum up

WebSocket uses the unified resource identifier of ws or wss, and determines whether it is currently necessary to upgrade to the websocket protocol by judging whether the header contains Connection: Upgrade and Upgrade: websocket. In addition, it also contains Sec-WebSocket-Key and Sec- For headers such as WebSocket-Version, when the server agrees to the WebSocket connection, it returns a response code of 101. Its API is very simple.

method:

socket.send(data)

socket.close([code], [reason])

event:

open

message

error

close

reference:

WebSocket: https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096

WebSocket: https://zh.javascript.info/websocket

WebSocket you don’t know: https://juejin.cn/post/6854573221241421838

From: https://github.com/Advanced-Frontend/Daily-Interview-Question

【Editor's Choice】