← 返回目录

第 16 卷

第 16 / 21 卷日期:

8Sec-WebSocket-Protocol: chat, game#可选:客户端支持的子协议,用于协商应用层协议
9Sec-WebSocket-Extensions: permessage-deflate#可选:请求启用的扩展(如数据压缩)

关键说明: Sec-WebSocket-Key 是客户端随机生成的16字节Base64编码字符串,用于后续服务端验证,避免恶意连接。

  1. 第二步:服务端验证并返回升级响应(握手确认)

服务端接收客户端的升级请求后,进行合法性验证(如验证 Origin 是否允许跨域、 Sec- WebSocket-Version 是否支持、 Sec-WebSocket-Key 是否有效),若验证通过,会返

回“HTTP 101 Switching Protocols”响应,告知客户端“升级成功”,响应头包含核心确认字段:

Code block

1HTTP/1.1 101 Switching Protocols

2Upgrade: websocket#确认升级到WebSocket协议
3Connection: Upgrade#确认连接为升级连接
4Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=#服务端计算的验证值
5Sec-WebSocket-Protocol: chat#确认使用的子协议(从客户端请求中选择)
6Sec-WebSocket-Extensions: permessage-deflate#确认启用的扩展

关键说明: Sec-WebSocket-Accept 是服务端通过 Sec-WebSocket-Key 计算得出的验证值,计算规则为:

  1. 将客户端发送的 Sec-WebSocket-Key 与固定字符串 "258EAFA5-E914-47DA-95CA-

C5AB0DC85B11" 拼接;

  1. 对拼接后的字符串进行SHA-1哈希计算,得到20字节的哈希值;
  2. 将哈希值转换为Base64编码,即为 Sec-WebSocket-Accept。

客户端会通过相同规则验证 Sec-WebSocket-Accept,验证通过则确认服务端是合法的 WebSocket服务器。

  1. 第三步:协议切换,建立全双工连接

客户端接收并验证服务端的101响应后,HTTP升级过程完成,底层传输协议从HTTP正式切换为 WebSocket:

  • TCP连接保持不变(握手过程复用TCP连接,无需重新建立);

• 后续数据传输不再使用HTTP协议,而是使用WebSocket的帧格式(包含操作码、数据长度、掩码

  • 客户端和服务端可通过该连接双向同时发送数据,实现全双工通信。
  1. 验证机制保障安全:通过 Sec-WebSocket-Key 和 Sec-WebSocket-Accept 的验证,避免

客户端误连非WebSocket服务端,同时防止恶意伪造升级请求;

  1. 兼容HTTP基础设施:握手过程基于HTTP,可穿过支持HTTP的防火墙、代理服务器和负载均衡

器,部署友好;

  1. 失败处理:若服务端不支持WebSocket或验证失败,会返回HTTP 4xx/5xx错误,客户端

WebSocket连接失败,触发 onerror 事件。

✅ 核心总结

WebSocket握手的核心是“HTTP升级+验证确认”:客户端通过HTTP请求发起升级协商,服务端验证后确认升级,最终完成协议切换,建立持久的全双工连接。这一过程既保障了与现有HTTP基础设施

的兼容性,又实现了从单向通信到双向通信的平滑过渡。

  1. 如何在前端应用中实现与WebSocket服务器的连接?

前端通过浏览器原生的 WebSocket API即可轻松实现与WebSocket服务器的连接,核心流程包括“创建连接、监听事件、发送数据、关闭连接”四个步骤,同时需处理异常情况(如连接失败、重

连),确保通信稳定性。以下是完整实现方案和注意事项:

一、核心实现步骤(基础版)

  1. 步骤1:创建WebSocket连接

通过 new WebSocket(url) 创建连接,URL需遵循WebSocket协议规范:

• 协议前缀: ws://(明文传输,类似HTTP)、 wss://(加密传输,类似HTTPS,推荐生产环

境使用);

• URL格式: ws://[域名]:[端口]/[路径](如 ws://example.com/ws、

wss://chat.example.com:8080/connect)。

代码示例:

Code block

1// 创建WebSocket连接(生产环境推荐wss://)

Code block

1// 1. 连接成功建立(open事件)

2ws.addEventListener("open", (event) => {
3console.log("WebSocket连接成功");
4//连接成功后可立即发送数据(如登录认证、初始化请求)
5ws.send(JSON.stringify({ type: "login", data: { userId: "123" } }));
6});

7 8// 2. 接收服务端发送的数据(message事件)

9ws.addEventListener("message", (event) => {
10console.log("收到服务端数据:", event.data);
11//处理数据(区分文本/二进制数据)
12if (typeof event.data === "string") {
13//文本数据(如JSON)
14const data = JSON.parse(event.data);
15handleTextData(data); //自定义处理逻辑
16} else {
17//二进制数据(如图片、音频)
18handleBinaryData(event.data); //自定义处理逻辑
19}
20});

21 22// 3. 连接发生错误(error事件)

23ws.addEventListener("error", (error) => {
24console.error("WebSocket连接错误:", error);
25//错误处理(如提示用户、触发重连)
26});

27 28// 4. 连接关闭(close事件)

29ws.addEventListener("close", (event) => {
30console.log("WebSocket连接关闭,代码:", event.code, "原因:", event.reason);
31//连接关闭处理(如自动重连、清理资源)
32if (event.wasClean) {
33console.log("连接正常关闭");
34} else {
35console.log("连接异常关闭,尝试重连...");
36reconnect(); //自定义重连函数
37}
38});
全站分卷索引 · 21 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷