WebSocket 协议是什么?
WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工(Full-Duplex)通信。
简单来说,它允许服务器主动向客户端推送数据。在 WebSocket 出现之前,Web 通信通常是单向的(客户端请求 -> 服务器响应),而 WebSocket 打破了这一限制,实现了真正的实时双向通信。
以下是关于 WebSocket 的详细解析:
1. 为什么需要 WebSocket?(背景与痛点)
在 WebSocket 出现之前,HTTP 协议存在一个核心限制:无状态、被动性。服务器无法主动向客户端发送信息,必须等待客户端发起请求。
为了实现“实时”效果(例如股票走势、聊天室),以前通常采用以下低效的方法:
- 轮询 (Polling): 客户端每隔几秒钟发送一次 HTTP 请求询问:“有新消息吗?”(浪费带宽,延迟高)。
- 长轮询 (Long Polling): 客户端发起请求,服务器保持连接打开,直到有新数据才响应。(虽然比轮询好,但仍有 HTTP 头部开销,且服务器资源占用高)。
WebSocket 的出现解决了这个问题: 它建立一次连接后,连接保持打开状态,双方可以随时互发数据,无需每次都重新建立 HTTP 连接。
2. WebSocket 的核心特点
- 全双工通信: 客户端和服务器可以同时向对方发送数据,互不干扰。
- 建立在 TCP 之上: 它是一个独立的基于 TCP 的协议,但与 HTTP 有良好的兼容性。
- 轻量级头部: 建立连接后,数据包的头部非常小(只有 2-14 字节),相比 HTTP 每次请求都要携带几百字节的头部(Cookie、User-Agent 等),大大节省了带宽。
- 持久连接: 只要不主动断开,连接一直保持。
3. WebSocket 是如何工作的?(握手过程)
WebSocket 复用了 HTTP 的握手通道。建立连接的过程如下:
客户端发起握手:
客户端发送一个标准的 HTTP GET 请求,但在 Header 中带上特殊的标记,告诉服务器:“我想把协议升级为 WebSocket”。plaintextGET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==服务器响应握手:
如果服务器支持 WebSocket,它会返回状态码101 Switching Protocols,表示同意升级协议。plaintextHTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=数据传输:
握手成功后,HTTP 协议也就完成了任务。接下来的通信完全遵循 WebSocket 协议(二进制帧),不再是 HTTP 请求了。
4. URL 格式
WebSocket 使用自定义的 URL 模式:
ws://(类似于http://,非加密)wss://(类似于https://,基于 TLS/SSL 加密,更安全)
5. 应用场景
任何需要低延迟、高频率、双向交互的场景都是 WebSocket 的用武之地:
- 即时通讯 (IM): 微信网页版、Slack、在线客服。
- 实时数据看板: 股票 K 线图、加密货币价格更新、体育比分直播。
- 多人在线游戏: 王者荣耀等游戏的实时操作同步。
- 协同编辑: Google Docs、Notion 多人同时编辑文档。
- 系统通知: 网页右上角的“新消息”红点推送。
6. 简单的代码示例 (JavaScript)
客户端 (浏览器):
javascript
// 1. 创建 WebSocket 连接
const socket = new WebSocket('wss://echo.websocket.org');
// 2. 连接打开时的回调
socket.addEventListener('open', function (event) {
console.log('连接已打开');
socket.send('你好,服务器!'); // 发送消息
});
// 3. 收到服务器消息时的回调
socket.addEventListener('message', function (event) {
console.log('收到服务器消息:', event.data);
});
// 4. 连接关闭时的回调
socket.addEventListener('close', function (event) {
console.log('连接已关闭');
});
总结
| 特性 | HTTP | WebSocket |
|---|---|---|
| 通信方式 | 单向(请求-响应) | 双向(全双工) |
| 连接状态 | 无状态,每次请求需新建连接(HTTP 1.1虽有Keep-alive但仍是被动的) | 有状态,持久连接 |
| 数据开销 | 大(每次包含完整 Header) | 极小(轻量级帧头) |
| 实时性 | 较低(依赖轮询) | 极高(实时推送) |
| 适用场景 | 浏览网页、API 调用 | 聊天、游戏、实时行情 |
WebSocket 是现代 Web 开发中实现实时功能的标准解决方案。