侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

WebSocket 握手过程及协议升级实现

2025-12-12 / 0 评论 / 4 阅读

题目

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协议升级机制:

  1. 客户端发起GET请求,携带Upgrade: websocketConnection: Upgrade
  2. 客户端生成随机16字节Base64编码作为Sec-WebSocket-Key
  3. 服务器用固定GUID拼接Key后做SHA1哈希,再Base64编码生成Sec-WebSocket-Accept
  4. 返回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全双工通信