用途
WebSocket 用于在客户端与服务端之间建立实时、双向的通信通道。它在单个 TCP 连接上将 HTTP 连接升级为持久、全双工的通道,适合需要服务端主动推送或双向交互的场景,例如聊天、实时更新、协作编辑和游戏。
协议基础
WebSocket 通过 HTTP 升级握手建立连接:客户端发送 HTTP Upgrade 请求,服务端返回 101 Switching Protocols。
握手请求示例:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
帧操作码包括:0x0 延续帧、0x1 文本帧(UTF-8)、0x2 二进制帧、0x8 连接关闭、0x9 ping、0xA pong。
关闭码包括:1000 正常、1001 离开、1006 异常(无关闭帧)、1008 策略违规、1011 服务端错误、1012 服务重启、1013 稍后重试。
主要能力
服务端实现
资料提供了 Node.js(ws)、Python(websockets)和 Go(gorilla/websocket)三种服务端实现示例。
Node.js 使用 ws 库创建 WebSocketServer,可监听连接、消息、关闭和错误事件,并支持向其他客户端广播消息。示例还包含心跳检测机制,通过定时 ping/pong 检测失效连接。
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
也可将 WebSocket 附加到现有 HTTP 服务器(如 Express)。
Python 使用 websockets 库,通过异步 handler 处理连接,并使用 websockets.broadcast 向所有已连接客户端广播。
Go 使用 gorilla/websocket,通过 Upgrader 升级连接,并在循环中读取和写入消息。
客户端 JavaScript
浏览器端使用原生 WebSocket API,支持 onopen、onmessage、onerror、onclose 事件,可发送文本和二进制数据(ArrayBuffer、Blob、TypedArray)。发送前可通过 readyState 检查连接状态(0=CONNECTING、1=OPEN、2=CLOSING、3=CLOSED)。二进制类型可通过 binaryType 设置为 'arraybuffer' 或 'blob'。
Socket.IO
Socket.IO 提供更高层的封装,包含服务端和客户端示例。服务端支持中间件(每个连接运行一次)、命名空间(namespaces)、房间(rooms)、事件监听与确认回调。客户端支持认证、自动重连配置(reconnection、reconnectionDelay、reconnectionDelayMax、reconnectionAttempts)。
认证模式
资料列出三种认证方式:查询参数携带 token(简单但会出现在日志中)、基于 Cookie(利用现有会话,升级请求自动携带)、首消息认证(连接后第一条消息发送 auth)。服务端可据此验证并在失败时以 1008 关闭连接。
重连与心跳
客户端可实现指数退避重连:根据重试次数计算延迟(baseDelay * 2^retries + 随机抖动),并设置最大延迟和最大重试次数。正常关闭(code 1000)不重连。客户端心跳通过定时发送 ping 消息实现。
扩展
水平扩展方面,Socket.IO 可使用 Redis 适配器(@socket.io/redis-adapter),使 io.emit() 能触达所有服务实例上的客户端。nginx 可通过 ip_hash 实现粘性会话,并配置 Upgrade/Connection 头及较长的读写超时(如 86400s)防止空闲连接被关闭。
消息模式
发布订阅模式:服务端维护 channel 到 WebSocket 集合的映射,处理 subscribe 和 publish 消息。
请求响应模式:客户端使用自增消息 ID 和 pending Map 实现关联,服务端返回带相同 ID 的响应,支持超时处理。
SSE 替代方案
当只需要服务端到客户端的推送时,可使用 Server-Sent Events(SSE)。SSE 比 WebSocket 更简单,可穿透代理,并自动重连。适用场景:通知、实时信息流、仪表盘、日志跟踪。WebSocket 适用于需要双向通信的场景:聊天、游戏、协作编辑。
限流
可对消息速率限流(如每秒最多 10 条),也可对连接级别限流(限制每个 IP 的新连接数,超出时以 1013 关闭)。
测试
可使用 wscat、websocat 命令行工具测试,或用 curl 检查升级握手。自动化测试可使用 Node.js 的 ws 库配合 node:test 编写。
使用方式
根据所用语言选择对应库:Node.js 使用 ws,Python 使用 websockets,Go 使用 gorilla/websocket,需要更高层封装时使用 Socket.IO。客户端使用浏览器原生 WebSocket API 或 socket.io-client。
适用场景
聊天应用(房间管理、消息持久化、在线状态、输入指示)、实时仪表盘、协作编辑、游戏等需要双向实时通信的场景。
限制
资料未提供关于收费、价格、平台限制或性能指标的信息。