WebSocket:新手如何秒懂服务器实时推送的核心协议?

摘要:初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
一、引言 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处? 在我们之前的教程中,我们在树莓派 Pico 上用 HTML 开发了一个基于 HTTP 协议的网页服务器,以此控制树莓派 Pico 的硬件引脚: https://freakstudio.cn/node/019bd0cf-8ca7-7e97-83fe-0b29d55c6f5c 这个方式非常简单,但缺点也非常明显:每次提交表单都需要完成一次完整的网络往返(也就是页面刷新),导致存在明显延迟,这种往返通信对用户体验很不友好,延迟会导致用户重复点击,或是感觉界面无响应。 HTTP 协议的核心模式是请求 - 响应:浏览器发起请求,服务器处理后返回响应。它属于​半双工​通信,同一时间只能单向传输数据,每次通信都需要重新建立握手连接。 对很多嵌入式项目来说,这种协议完全够用:比如用浏览器配置开发板参数,之后开发板独立运行一段时间,但是考虑下面两个情况: ​温湿度实时记录和显示:​如果使用 HTTP,浏览器必须不断轮询(例如每隔 1 秒请求一次数据),服务器才能返回最新的温湿度值;这样会带来几个问题: 请求频率高,浪费带宽和 MCU 资源; 数据存在延迟(取决于轮询间隔); 设备功耗增加(频繁网络通信)。 ​在线网络聊天室:​如果使用 HTTP,客户端需要不断轮询服务器是否有新消息(例如每几百毫秒请求一次)。这样不仅效率低,还会造成: 大量无效请求(大部分时候没有新消息); 服务器压力增大; 消息延迟明显,体验差。 你可以看到,在需要服务器可以在有新消息时立即推送给所有客户端的情况下,使用 HTTP 通信并不友好。 那么,我们实际上可以选择另一种更优的方案:​在浏览器与服务器之间建立并保持一个长连接​​,实现全双工通信​。 在这种模式下,客户端和服务器都可以在任意时刻主动发送数据,不再受限于 HTTP “请求 - 响应”的单向通信机制,从而避免频繁轮询带来的性能浪费和延迟问题。 这种通信方式特别适合​需要实时数据更新和即时交互反馈的场景​,例如实时监控、在线聊天、远程控制等。 而实现这一能力的核心协议,就是 ​WebSocket​。 客户端(如浏览器)向服务器发起连接请求,经一次 HTTP 握手完成协议升级后,建立持久全双工长连接。 二、WebSocket 协议介绍 2.1 基本概念 它于 2008 年诞生,2011 年成为国际标准: WebSocket 最初在 HTML5 规范中以 TCPConnection 为名,作为基于 TCP 的套接字 API 的占位方案,用于解决浏览器端原生 TCP 通信的需求。 在 WebSocket 出现前,浏览器端端口 80 的全双工通信依赖 Comet 通道 技术,但存在两大核心缺陷: 实现复杂度高,部署与维护成本大; 因 TCP 三次握手、HTTP 请求头的额外开销,对小消息场景的传输效率极低。 2008 年 6 月,Michael Carter 牵头系列技术讨论,产出了首个名为「WebSocket」的协议版本,核心目标是在不破坏网络安全假设的前提下,解决 Comet 技术的痛点; 随后 Ian Hickson 与 Michael Carter 合作确定 WebSocket 这一名称,由 Ian Hickson 正式写入 HTML5 规范。 目前​所有浏览器均已原生支持​,无需额外插件,包括 Google Chrome、Firefox、Microsoft Edge、Internet Explorer、Safari 和 Opera,其属于​真正的双向平等对话​,支持服务器主动向客户端推送信息,也支持客户端主动向服务器发消息,属于主流的服务器推送技术之一。 其技术特点包括: 基于 TCP​ 协议 构建,服务器端实现逻辑简单,适配性强。 完美兼容 HTTP 生态,​默认共用 80(ws​​)、443(wss)端口​; 握手阶段采用 HTTP 协议,不易被网络屏蔽,可顺利通过各类 HTTP 代理服务器。 数据格式轻量化,​通信开销小、效率高​; 支持文本、二进制数据双向传输,覆盖文字、文件、音视频等各类数据场景。 ​无同源限制​,客户端可与任意服务器建立连接,突破浏览器同源策略限制; 协议标识符:​ws​(未加密)、​wss​(加密,类似 HTTPS),通信地址遵循 URL 规范,示例:ws://​example.com:80/some/path。
阅读全文