一、握手阶段(HTTP 升级请求)
1. 请求行参数
• 格式:GET /{path}?{query} HTTP/1.1
• /{path}
服务端监听路径,用于指定 WebSocket 服务端点(如 /chat
)。支持路径参数动态匹配(如 /room/123
)。
• ?{query}
附加查询参数,常用于身份验证(如 token=abc
)或传递初始化数据。需手动解析键值对。
2. 必需请求头
请求头 | 作用与格式 | 示例 |
---|---|---|
Upgrade | 固定为 websocket ,声明协议升级。 |
Upgrade: websocket |
Connection | 固定为 Upgrade ,表示需保持长连接。 |
Connection: Upgrade |
Sec-WebSocket-Key | 客户端生成的 16 字节随机数 Base64 编码,用于安全验证。服务端需将其与 GUID 拼接后计算 SHA-1 哈希并返回 Sec-WebSocket-Accept 。 |
Sec-WebSocket-Key: dGhlIHNhbXBsZQ== |
Sec-WebSocket-Version | 固定为 13 ,表示使用 WebSocket 协议第 13 版。 |
Sec-WebSocket-Version: 13 |
3. 可选请求头
请求头 | 作用与格式 | 示例 |
---|---|---|
Origin | 请求来源域名,用于跨域策略验证。若为空或未授权,服务端可拒绝连接。 | Origin: http://client-domain.com |
Sec-WebSocket-Protocol | 客户端支持的子协议列表(如 chat 、binary ),服务端需选择其一返回。 |
Sec-WebSocket-Protocol: chat, video |
Cookie | 传递 HTTP 会话 Cookie,用于身份关联(需服务端配置支持)。 | Cookie: sessionId=abc123 |
Authorization | 身份验证凭证(如 Bearer Token ),替代 URL 参数传递敏感信息。 |
Authorization: Bearer eyJhbGci... |
二、客户端构造函数参数(WebSocket API)
1. url
参数
• 格式:ws://host:port/path?query
或 wss://host:port/path?query
• ws
vs wss
:ws
为明文协议(默认端口 80),wss
为加密协议(默认端口 443)。
• 动态路径:支持路径参数(如 /user/123
),服务端可通过解析路径实现资源隔离。
2. protocols
参数
• 作用:声明客户端支持的子协议列表(字符串或数组),服务端选择其一返回 Sec-WebSocket-Protocol
响应头。
// 示例:声明两种子协议
const socket = new WebSocket("ws://example.com", ["chat-v1", "binary-v2"]);
三、数据传输阶段参数(数据帧格式)
WebSocket 数据帧由以下字段构成,用于控制数据传输:
字段名 | 长度(位) | 作用与取值 |
---|---|---|
FIN | 1 | 标识是否为消息的最后一个分片(1=结束,0=还有后续帧)。 |
RSV1-3 | 3 | 保留位,需为 0(除非协商了扩展)。 |
Opcode | 4 | 定义数据类型: • 0x1 文本帧• 0x2 二进制帧• 0x8 关闭帧• 0x9 Ping 帧等。 |
Mask | 1 | 客户端到服务端的数据必须掩码(1=启用,0=禁用)。服务端到客户端禁止掩码。 |
Payload Length | 7/16/64 | 负载长度: • 0-125:直接表示长度 • 126:后 2 字节为长度 • 127:后 8 字节为长度。 |
Masking-Key | 32 | 掩码密钥(仅当 Mask=1 时存在),用于异或运算解码负载数据。 |
Payload Data | 可变 | 实际传输的数据(如 JSON、二进制流)。 |
四、关键验证与处理逻辑
安全握手验证
服务端需计算Sec-WebSocket-Accept
:key = client_key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" accept = base64(sha1(key))
若验证失败,返回
401 Unauthorized
并关闭连接。跨域处理
服务端需在响应头添加Access-Control-Allow-Origin
,或通过拦截器动态验证Origin
头。子协议协商
服务端从客户端Sec-WebSocket-Protocol
中选择支持的协议,返回给客户端以实现多逻辑分支处理。
五、常见问题与调试
• 连接失败:检查端口是否开放、路径是否匹配、跨域策略是否允许。
• 数据解析错误:验证 Opcode
类型与负载格式是否一致,或检查掩码解码逻辑。
• 性能优化:使用二进制帧(Opcode=0x2
)传输结构化数据(如 Protobuf),减少带宽占用。
通过合理配置上述参数,可构建高效、安全的实时通信系统。具体实现可参考各语言库(如 Node.js 的 ws
或 Java 的 Tyrus
)的文档。