题目
WebSocket 握手过程及协议升级实现
信息
- 类型:问答
- 难度:⭐⭐
考点
WebSocket握手过程,HTTP协议升级,WebSocket协议头字段
快速回答
WebSocket握手核心过程:
- 客户端发送HTTP Upgrade请求,包含
Sec-WebSocket-Key等头字段 - 服务器响应101状态码,返回
Sec-WebSocket-Accept验证值 - 连接升级为全双工WebSocket协议
- 关键验证:
Sec-WebSocket-Accept= base64(sha1(Sec-WebSocket-Key+ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
原理说明
WebSocket握手是基于HTTP协议升级机制:
- 客户端发起GET请求,携带
Upgrade: websocket和Connection: Upgrade头 - 客户端生成随机16字节Base64编码作为
Sec-WebSocket-Key - 服务器用固定GUID拼接Key后做SHA1哈希,再Base64编码生成
Sec-WebSocket-Accept - 返回101状态码完成协议升级
代码示例(Node.js实现)
// 客户端握手请求示例
const clientRequest = `GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13`;
// 服务器端握手处理
const crypto = require('crypto');
function handleHandshake(request) {
const key = request.headers['sec-websocket-key'];
const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
// 计算Accept值
const accept = crypto.createHash('sha1')
.update(key + GUID)
.digest('base64');
return `HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: ${accept}`;
}最佳实践
- 安全验证:严格校验
Origin头防止CSRF攻击 - 协议协商:使用
Sec-WebSocket-Protocol支持子协议(如wamp、soap) - 错误处理:对非法握手请求返回400错误而非101
- 性能优化:复用HTTP服务器端口(80/443)减少连接开销
常见错误
- 未正确处理多值
Connection头(如Connection: keep-alive, Upgrade) - 未验证
Sec-WebSocket-Accept导致兼容性问题 - 忽略
Sec-WebSocket-Version协商(当前必须为13) - 在握手响应中遗漏
Upgrade头字段
扩展知识
- 协议设计:WebSocket帧结构含FIN/RSV/Opcode/Mask/Payload Len等字段
- 心跳机制:通过Ping/Pong帧(opcode 0x9/0xA)维持连接
- WSS安全:wss://实际在TLS之上运行WebSocket,加密握手过程
- 与HTTP/2对比:HTTP/2的Server Push不能替代WebSocket全双工通信