news 2026/6/24 3:02:01

10-WebSocket 实时通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
10-WebSocket 实时通信

WebSocket 实时通信

从 HTTP 轮询到 WebSocket:掌握浏览器与服务器的全双工实时通信技术


学习目标

读完本文,你将学会:

  • 理解 WebSocket 与 HTTP 轮询的本质区别
  • 掌握 WebSocket API 的完整使用方法
  • 实现心跳检测、断线重连等生产级功能
  • 对比 WebSocket、SSE、长轮询的适用场景

一、为什么需要 WebSocket

1.1 HTTP 的局限性

HTTP 是请求-响应模型:客户端发起请求,服务器才能响应。服务器无法主动向客户端推送数据。

客户端 ──请求──▶ 服务器 客户端 ◀──响应── 服务器 (服务器无法主动说"有新消息了")

1.2 实时通信方案的演进

方案原理延迟资源消耗适用场景
短轮询客户端定时发送 HTTP 请求取决于轮询间隔高(大量无效请求)简单场景
长轮询服务器挂起请求直到有数据接近实时中(连接保持)兼容旧浏览器
SSE (Server-Sent Events)HTTP 长连接,服务器单向推送股票行情、新闻推送
WebSocketTCP 全双工连接极低聊天、游戏、协同编辑
短轮询: 请求→响应 请求→响应 请求→响应 (频繁往返) 长轮询: 请求→等待→响应 请求→等待→响应 (减少部分往返) SSE: 连接建立→服务器持续推送→推送→推送 (单向) WebSocket: 握手一次→双向自由通信 (全双工)

1.3 WebSocket 的优势

  • 全双工通信:客户端和服务器可同时发送数据
  • 低延迟:建立连接后无需重复握手
  • 低开销:数据帧头仅 2-14 字节,远小于 HTTP 头
  • 跨域支持:原生支持 CORS

二、WebSocket 协议基础

2.1 握手过程

WebSocket 连接始于一次 HTTP 升级请求:

GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13

服务器响应:

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

之后,TCP 连接从 HTTP 协议切换为 WebSocket 协议。

2.2 数据帧结构

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - -+ : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+
  • FIN:是否为最后一帧
  • opcode:操作码(1=文本,2=二进制,8=关闭,9=ping,10=pong)
  • MASK:客户端发送的数据必须掩码
  • Payload len:负载长度(0-125 直接表示,126 则用后续 2 字节,127 用 8 字节)

三、WebSocket API 详解

3.1 创建连接

constws=newWebSocket('wss://echo.websocket.org/');// 连接成功ws.onopen=()=>{console.log('连接已建立');ws.send('Hello Server!');};// 接收消息ws.onmessage=(event)=>{console.log('收到:',event.data);};// 连接关闭ws.onclose=(event)=>{console.log('连接关闭',event.code,event.reason);};// 发生错误ws.onerror=(error)=>{console.error('WebSocket 错误:',error);};

3.2 连接状态

console.log(ws.readyState);// CONNECTING = 0 连接中// OPEN = 1 已连接// CLOSING = 2 关闭中// CLOSED = 3 已关闭

3.3 发送数据

// 发送文本ws.send('文本消息');// 发送二进制(Blob)constblob=newBlob(['二进制数据'],{type:'text/plain'});ws.send(blob);// 发送 ArrayBufferconstbuffer=newArrayBuffer(8);ws.send(buffer);

3.4 关闭连接

// 正常关闭(code 1000 表示正常关闭)ws.close(1000,'用户主动关闭');

常用关闭码:

状态码含义
1000正常关闭
1001终端离开(如浏览器关闭)
1006异常关闭(连接意外断开)
1008策略违反
1011服务器错误

四、生产级 WebSocket 封装

4.1 心跳检测

长时间无数据传输,中间代理可能断开连接。心跳机制保持连接活跃:

classHeartbeatWebSocket{constructor(url){this.url=url;this.ws=null;this.heartbeatInterval=30000;// 30 秒this.heartbeatTimer=null;}connect(){this.ws=newWebSocket(this.url);this.ws.onopen=()=>{this.startHeartbeat();};this.ws.onmessage=(event)=>{if(event.data==='pong')return;// 忽略心跳响应this.onMessage?.(event.data);};this.ws.onclose=()=>{this.stopHeartbeat();};}startHeartbeat(){this.heartbeatTimer=setInterval(()=>{if(this.ws.readyState===WebSocket.OPEN){this.ws.send('ping');}},this.heartbeatInterval);}stopHeartbeat(){clearInterval(this.heartbeatTimer);}}

4.2 断线重连

classReconnectWebSocket{constructor(url,options={}){this.url=url;this.reconnectInterval=options.reconnectInterval||3000;this.maxReconnectAttempts=options.maxReconnectAttempts||5;this.attempts=0;this.ws=null;}connect(){this.ws=newWebSocket(this.url);this.ws.onopen=()=>{this.attempts=0;console.log('连接成功');};this.ws.onclose=()=>{this.attemptReconnect();};this.ws.onerror=()=>{this.ws.close();};}attemptReconnect(){if(this.attempts>=this.maxReconnectAttempts){console.error('重连次数已达上限');return;}this.attempts++;console.log(`${this.attempts}秒后尝试重连...`);setTimeout(()=>this.connect(),this.reconnectInterval);}}

完整代码见CODE-ADVANCED/10-WebSocket实时通信/websocket-reconnect.js


五、实战案例:实时聊天室

5.1 需求分析

  • 多用户实时收发消息
  • 显示在线用户列表
  • 消息历史记录

5.2 客户端实现

constchat={ws:null,username:'',connect(name){this.username=name;this.ws=newWebSocket('wss://chat.example.com');this.ws.onopen=()=>{this.send({type:'join',username:name});};this.ws.onmessage=(event)=>{constmsg=JSON.parse(event.data);switch(msg.type){case'message':this.displayMessage(msg);break;case'userList':this.updateUserList(msg.users);break;case'system':this.displaySystem(msg.text);break;}};},send(data){if(this.ws.readyState===WebSocket.OPEN){this.ws.send(JSON.stringify(data));}},sendMessage(text){this.send({type:'message',text,from:this.username});}};

完整代码见CODE-ADVANCED/10-WebSocket实时通信/websocket-chat.html


六、WebSocket vs SSE vs 长轮询

┌─────────────────┬──────────────┬──────────────┬──────────────┐ │ 特性 │ WebSocket │ SSE │ 长轮询 │ ├─────────────────┼──────────────┼──────────────┼──────────────┤ │ 通信方向 │ 双向 │ 服务器→客户端 │ 双向(伪) │ │ 协议 │ TCP (ws/wss) │ HTTP │ HTTP │ │ 实时性 │ 极高 │ 高 │ 中 │ │ 浏览器兼容 │ IE10+ │ IE 不支持 │ 全部 │ │ 自动重连 │ 需手动实现 │ 原生支持 │ 需手动实现 │ │ 二进制数据 │ 支持 │ 不支持 │ 需 Base64 │ │ 多域名连接 │ 有限制 │ 无限制 │ 无限制 │ │ 防火墙穿透 │ 可能受阻 │ 易穿透 │ 易穿透 │ └─────────────────┴──────────────┴──────────────┴──────────────┘

选择建议

  • 需要双向实时(聊天、游戏)→ WebSocket
  • 仅需服务器推送(股票、日志)→ SSE
  • 需要兼容旧浏览器→ 长轮询

二、常见误区与注意点

误区正确做法
WebSocket 可以替代所有 HTTPWebSocket 用于实时场景,REST API 仍适合 CRUD
连接永不关闭页面切换/网络变化时连接会断开,需处理重连
不需要考虑兼容性IE9 及以下不支持,需准备降级方案
所有数据都用 WebSocket文件上传等大流量操作仍用 HTTP 更合适
忽略错误处理必须处理 onerror、onclose,实现重连策略

三、动手练习

练习 1:心跳检测实现

在基础 WebSocket 连接上添加心跳机制,如果 3 次心跳无响应则认为连接已断开,触发重连。

练习 2:简易协同白板

使用 WebSocket 实现多人实时绘图:鼠标移动时发送坐标,其他客户端实时绘制。


四、AI 辅助学习

4.1 本节知识点的 AI 提问模板

  • “WebSocket 的 Sec-WebSocket-Key 是如何生成的?”
  • “如何在 WebSocket 中实现消息确认机制(ACK)?”
  • “WebSocket 连接数有浏览器限制吗?”

4.2 用 AI 验证你的理解

尝试向 AI 描述 WebSocket 握手过程,让它判断你的理解是否正确。

4.3 警惕 AI 的常见错误

  • AI 可能混淆 WebSocket 和 Socket.IO(后者是库,不是协议)
  • AI 可能忘记提到 WebSocket 的掩码机制

五、配套代码

本文示例代码位于:CODE-ADVANCED/10-WebSocket实时通信/

文件名说明
websocket-basic.htmlWebSocket API 基础演示
websocket-chat.html实时聊天室完整实现
websocket-reconnect.js断线重连与心跳封装

六、本章小结

  • WebSocket 通过 HTTP 升级握手建立 TCP 全双工连接
  • 心跳检测和断线重连是生产环境的必备功能
  • WebSocket 适合双向实时场景,SSE 适合单向推送
  • 注意处理连接状态、错误情况和浏览器兼容性

如果本文对你有帮助,欢迎点赞、收藏、关注专栏。有任何问题可以在评论区交流!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 2:59:10

从 OpenRouter 到 Vapeur AI:多模型统一接入为什么会成为开发标配?

OpenRouter真正吸引人的地方,并不只是“能用更多模型”,而是解决了一个越来越现实的问题:AI 应用正在从调用单一模型,走向管理一组模型能力。今天做 AI 应用,开发者通常不会只依赖一个模型。日常问答、复杂推理、AI Co…

作者头像 李华
网站建设 2026/6/24 2:53:54

如何快速上手PyPDF:Python PDF处理的完整指南

如何快速上手PyPDF:Python PDF处理的完整指南 【免费下载链接】pypdf A pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files 项目地址: https://gitcode.com/GitHub_Trending/py/pypdf PyPDF是一个…

作者头像 李华
网站建设 2026/6/24 2:53:33

简述:一种万物互联智能体工作流平台整体设计方案

简述:一种万物互联智能体工作流平台整体设计方案 一、平台定位 万物互联智能体工作流平台:面向设备、数据、系统、人员、业务全要素互联互通,以智能体(Agent)为最小执行单元,替代传统固定工作流&#xff…

作者头像 李华
网站建设 2026/6/24 2:53:16

WeChatMsg:三步永久备份微信聊天记录的终极指南

WeChatMsg:三步永久备份微信聊天记录的终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg …

作者头像 李华