WebSocket 与观察者模式(Observer Pattern):
- ∙WebSocket 的 API 设计(如
onopen、onmessage、onclose、onerror)本质上是 事件驱动 的 - ∙你可以理解为:
- ∙WebSocket 对象是被观察者(Subject)
- ∙你通过绑定事件回调函数,成为了 观察者(Observer)
- ∙当 WebSocket 状态发生变化(连接打开、收到消息、关闭等),底层会 主动通知(触发)你注册的回调函数
- ∙这种机制 非常符合观察者模式的思想:订阅事件,接收通知
🎯 什么是 WebSocket?
WebSocket 是一种网络通信协议,提供客户端与服务器之间的 全双工、长连接、低延迟 的通信能力。它使得浏览器和服务器之间可以像 "打电话" 一样随时双向发送消息,而不需要像 HTTP 那样 "请求-响应" 模式下反复建立连接。
✅ 与 HTTP 的主要区别:
| 特性 | HTTP | WebSocket |
|---|---|---|
| 连接方式 | 短连接,每次请求都要建立连接 | 长连接,一次握手后保持连接 |
| 通信模式 | 单向(客户端请求,服务器响应) | **全双工(双方可随时主动发消息)** |
| 协议 | 基于 HTTP(端口 80/443) | 基于 TCP(通过 HTTP 升级握手) |
| 实时性 | 延迟高,需轮询或长轮询 | 低延迟,实时通信 |
| 头部开销 | 每次请求都有较大 HTTP 头 | 握手后只有很小数据帧头 |
✅ WebSocket 建立连接的流程(握手过程):
-
1.客户端发起一个 HTTP 请求,请求 "升级" 到 WebSocket 协议:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13 -
2.服务器收到后,如果支持 WebSocket,会返回如下响应,表示同意升级:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
✅ 一旦握手成功,连接就从 HTTP "升级" 为 WebSocket 协议,此后双方可以随时通过 TCP 通道双向收发数据帧。
✅ 数据传输阶段:
∙双方通过 **WebSocket 数据帧(Frame)** 来收发消息
∙消息可以是文本(Text)、二进制(Binary)、控制帧(如 Ping/Pong、关闭帧)
🔍 WebSocket 的事件监听机制(类似观察者订阅事件):
当你创建一个 WebSocket 对象后,可以给它绑定一系列事件监听,比如:
javascript
const socket = new WebSocket('ws://example.com/socket');
// 👇 这些事件监听,就是 "观察者" 在订阅 WebSocket 的状态变化和消息
socket.onopen = function (event) {
console.log('WebSocket 连接已打开');
};
socket.onmessage = function (event) {
console.log('收到消息:', event.data); // 服务器发来的数据
};
socket.onclose = function (event) {
console.log('WebSocket 连接已关闭');
};
socket.onerror = function (error) {
console.log('WebSocket 发生错误');
};
✅ 对应观察者模式的角色:
| 角色 | WebSocket 中的对应 |
|---|---|
| **Subject(被观察者)** | WebSocket 对象本身(即 socket) |
| **Observer(观察者)** | 你通过 onopen / onmessage / onclose / onerror 注册的回调函数 |
| **事件(通知)** | 连接打开、收到消息、连接关闭、出错等 |
| **订阅(注册监听)** | 你通过给 WebSocket 添加事件处理器来 "订阅" 这些事件 |
| **通知(触发回调)** | 当 WebSocket 状态发生变化时(比如收到消息),底层会自动调用你注册的对应函数 |
✅ 如何检查 WebSocket 的连接状态?
👉 readyState
它表示当前 WebSocket 连接所处的状态,是一个 只读属性,值为数字,对应以下枚举:
| 值 | 含义 | 对应常量(WebSocket 对象上的) |
|---|---|---|
| 0 | CONNECTING:连接还未建立,正在握手 | WebSocket.CONNECTING |
| 1 | OPEN:连接已建立,可以通信 | WebSocket.OPEN |
| 2 | CLOSING:连接正在关闭 | WebSocket.CLOSING |
| 3 | CLOSED:连接已关闭或无法打开 | WebSocket.CLOSED |
✅ 示例:检查 WebSocket 状态
javascript
const socket = new WebSocket('ws://example.com/socket');
console.log(socket.readyState); // 0 (正在连接中)
socket.onopen = function () {
console.log('连接已打开!状态为:', socket.readyState); // 1
};
socket.onclose = function () {
console.log('连接已关闭!状态为:', socket.readyState); // 3
};
✅ 你也可以这样判断:
javascript
if (socket.readyState === WebSocket.OPEN) {
console.log('WebSocket 已连接,可以发送消息');
socket.send('Hello Server!');
} else {
console.log('WebSocket 尚未连接,状态码:', socket.readyState);
}
| 场景类型 | 是否推荐使用 WebSocket | 原因 |
|---|---|---|
| 实时数据大屏 / 监控面板 | ✅ 推荐 | 实时更新,避免轮询 |
| 消息通知 / 即时通讯 | ✅ 推荐 | 服务端主动推送,实时提醒 |
| 多用户协同 / 多端同步 | ✅ 推荐 | 实时同步操作与状态 |
| 系统告警 / 异常推送 | ✅ 推荐 | 紧急情况,实时通知 |
| 普通 CRUD 页面 | ❌ 不推荐 | 实时性要求低,常规请求足够 |
| 低频更新的数据页 | ❌ 不推荐 | 无需实时推送 |