# WebSocket 简介

WebSocket 是一种通信协议，它通过 single TCP connection 提供全双工通信通道（channel）。

当前允许 Web 应用程序使用此协议的 API 规范称为 WebSockets。

1. 在 HTML5 规范中，WebSocket 最开始被称为 TCPConnection（作为基于 TCP socket API 占位符
2. 2008 年，经过了一系列讨论，更名为 WebSocket
3. 2009 年，Chrome 4 成为第一个完全支持该标准的浏览器，默认启用 WebSocket
4. 2010 年，WebSocket 协议从 W3C 和 [WHATWG](https://websockets.spec.whatwg.org/) 小组转移到了 IETF
5. 2011 年，由 IETF 标准化为 RFC [6455](https://datatracker.ietf.org/doc/html/rfc6455)

和 HTTP 一样，WebSocket 也位于 OSI 模型中的第 7 层，并依赖于第 4 层的 TCP。

尽管和 HTTP 协议不同，但 RFC 6455 指出 WebSocket 被设计为工作在 HTTP 的端口 443 和 80 上，并且也支持 HTTP 代理和中介，所以 WebSocket 是和 HTTP 兼容的。为了实现这种兼容性，WebSocket 的握手用的是 HTTP Upgrade header，以从 HTTP 协议更改到 WebSocket 协议。

<figure><img src="/files/o6tbMJA9uTYnh2nkmb9D" alt=""><figcaption></figcaption></figure>

```http
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
```

```http
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
```

与 HTTP 不同，WebSocket 提供全双工通信。客户端和服务器之间可以进行双向持续对话。

此外，WebSocket 支持 TCP 之上的 message stream（消息流）。TCP 单独处理 byte stream（字节流），没有 message 的固有概念。使用浏览器开发人员工具，开发人员可以检查 WebSocket 握手以及 WebSocket 帧（frames）。

```js
// 客户端示例
const socket = new WebSocket('wss://game.example.com/ws/updates')

socket.onopen = () => {
  setInterval(() => {
    if (socket.bufferedAmount == 0)
      socket.send(getUpdateData())
  }, 50)
}

socket.onmessage = (event) => { }
socket.onclose = (event) => { }
socket.onerror = (event) => { }
```

服务器端

* 2013 年，Nginx 1.3.13 支持 WebSocket，包括充当 WebSocket 应用程序的反向代理和负载均衡器
* 2013 年 7 月，Apache HTTP Server 2.4.5 支持 WebSocket
* IIS 在随 Windows Server 2012 一起发布的版本 8 中添加了对 WebSockets 的支持
* 2017 年，lighttpd 1.4.46 支持 WebSockets


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://anjia1.gitbook.io/cs/protocol/websocket.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
