1、WebSocket基础:什么是WebSocket、WebSocket与HTTP的区别、WebSocket协议握手过程、WebSocket的优势与应用场景
各位同学,咱们今天正式开始聊WebSocket。说实话,我第一次接触这个协议的时候,心里想的是:「这不就是HTTP加了个长连接吗?」后来踩了坑才发现,完全不是那么回事。
WebSocket,说白了,是一种在单个TCP连接上进行全双工通信的协议。什么叫全双工?就是客户端和服务器可以同时给对方发数据,不用等对方先说完。这跟打电话一样——两边都能随时说话。
1.1 什么是WebSocket
WebSocket是HTML5规范的一部分,它提供了一个标准化的方式,让浏览器和服务器之间建立一条持久化的连接。这条连接一旦建立,双方就可以随时互推数据。
我习惯把它理解成「TCP的升级版」——它底层走的还是TCP,但加了一层轻量级的帧封装。你想想看,如果没有WebSocket,网页想实时拿数据,只能用轮询或者长轮询,那效率……嗯,我后面会细说。
核心特点:
- 建立在TCP之上,但自带协议帧
- 支持文本和二进制数据
- 真正的全双工通信
- 跨域友好(同源策略限制比HTTP松)
1.2 WebSocket与HTTP的区别
这个问题面试经常问,我当年也被问过。咱们直接上表格对比,一目了然:
| 对比项 | HTTP | WebSocket |
|---|---|---|
| 通信模式 | 半双工(请求-响应) | 全双工(双向随时发) |
| 连接状态 | 无状态,每次请求独立 | 有状态,连接保持 |
| 数据格式 | 文本(HTTP报文) | 文本或二进制帧 |
| 实时性 | 差(需要轮询) | 强(服务器主动推送) |
| 开销 | 每次请求都有HTTP头部 | 建立连接后头部极小 |
| 典型场景 | 网页浏览、API调用 | 实时聊天、游戏、数据推送 |
我在项目中遇到过最典型的例子:用HTTP轮询做实时数据展示,每秒钟发一次请求,服务器CPU直接飙到80%。换成WebSocket后,CPU降到10%以下。说白了,HTTP是为「请求-响应」设计的,WebSocket是为「实时通信」设计的,两者定位完全不同。
1.3 WebSocket协议握手过程
这个握手过程,我建议你把它记牢。因为很多坑都出在这里。握手分三步:
- 客户端发起HTTP升级请求:客户端发一个特殊的HTTP GET请求,头部包含
Upgrade: websocket和Sec-WebSocket-Key。 - 服务器响应升级:服务器计算出一个
Sec-WebSocket-Accept值,返回101状态码。 - 连接升级成功:之后双方就切换到WebSocket协议,不再使用HTTP。
来看一个实际的握手请求示例:
// 客户端请求
GET /chat HTTP/1.1
Host: 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=
小技巧:我曾经调试一个WebSocket连接失败的问题,查了半天发现是代理服务器把Upgrade头部给过滤了。所以如果你在生产环境用WebSocket,一定要确认中间设备(Nginx、负载均衡等)支持WebSocket协议转发。
1.4 WebSocket的优势与应用场景
优势其实前面已经提到了不少,我总结一下:
- 低延迟:建立连接后,数据帧头部只有2-14字节,比HTTP头部小得多
- 节省带宽:没有重复的HTTP头部开销
- 服务器主动推送:这是最核心的优势,不需要客户端轮询
- 跨平台:浏览器、Node.js、嵌入式设备都支持
应用场景嘛,我挑几个典型的说说:
- 实时数据仪表盘:比如ESP32采集传感器数据,推送到网页展示
- 在线聊天/协作:微信网页版、在线文档
- 游戏:多人在线游戏的状态同步
- 物联网设备控制:手机远程控制家里的ESP32设备
注意:WebSocket虽然强大,但不是万能的。如果你只是偶尔获取一次数据,用HTTP反而更简单。我见过有人为了推送一个「每日问候」消息,硬上了WebSocket,结果维护成本翻了好几倍。选技术方案,合适最重要。
好了,这一章的基础概念就讲到这里。下一章咱们会动手写一个ESP32上的WebSocket客户端,真正跑起来看看效果。你想想看,当你的ESP32能主动把温度数据推送到浏览器时,那种感觉还是挺爽的。