一、EventSource 浏览器实时通信
EventSource 也是sse(Server-Sent Events)单向通讯,服务器到客户端
客户端只能接收,支持断线重连和事件 ID 追踪。
// 创建 EventSource 连接
const eventSource = new EventSource('/api/events'); // 基于 HTTP 协议,浏览器会自动补全相对路径(http:// 或 https://)
// 监听默认消息,只能接收文本数据
eventSource.onmessage = (event) => {
console.log('收到消息:', event.data);
};
// 监听打开连接
eventSource.onopen = () => {
console.log('连接已建立');
};
// 监听错误,原生支持自动重连
eventSource.onerror = (err) => {
console.log('连接断开,正在尝试重连...');
};
// 关闭连接,只能重新 new EventSource() 建立连接。
eventSource.close();
// EventSource API 本身没有 onclose 事件
二、WebSocket双向全双工通信
客户端和服务器都能主动发送消息,建立连接后保持长连接。没有自动重连。
-
客户端发起 HTTP 请求,携带Upgrade: websocket和Connection: Upgrade头。 -
服务器同意升级,返回101 Switching Protocols状态码。 -
连接保持打开,双方可随时发送数据。
// 创建 WebSocket 连接
const webSocket = new WebSocket('ws://localhost:3000/chat'); // 基于 WebSocket 协议,自动补全 ws:// 或 wss://webSocket.onopen=(events)=>{
console.log('WebSocket 连接已建立');
};webSocket.onmessage=(events)=>{
console.log("收到信息",events.data);
};
// 也可以发送消息
webSocket.send("客户端消息");webSocket.onerror=(events)=>{
console.error('WebSocket 错误:', events);
};webSocket.close();
webSocket.onclose=(events)=>{
console.error('WebSocket 连接已关闭:', events);
};send() 方法可以发送以下类型的数据:
String 'hello' 文本消息(最常用)
Blob new Blob([...]) 二进制大对象
ArrayBuffer new ArrayBuffer(8) 原始二进制数据
TypedArray new Uint8Array([1,2,3]) 类型化数组(Int8Array, Uint8Array 等)// 接收二进制数据的格式,需要设置
ws.binaryType = 'arraybuffer'; // 默认 'blob',可选 'arraybuffer'
三、BroadcastChannel 广播机制
同一浏览器内通信,用于多标签页数据同步,不经过网络,完全本地。可以发送任意可序列化数据(通过结构化克隆算法)
浏览器内部维护了一个频道注册表,所有使用相同名称创建的 BroadcastChannel 实例都会自动关联到同一个逻辑频道。
一对多消息分发,不会发送给自己。
// 页面1
const channel = new BroadcastChannel('cart_channel');
channel.postMessage({ action: 'add', product: { id: 1, name: '商品A' } });
// 页面2、3、4... 所有同源且加入同一频道的页面都会收到
const channel = new BroadcastChannel('cart_channel');
channel.onmessage = (event) => {
console.log('所有页面同步更新购物车:', event.data);
};
channel.close() //释放资源,避免内存泄漏。