Appearance
sse和websocket
SSE(Server-Sent Events)
一个 EventSource 实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream 格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close() 关闭。
js
const eventSource = new EventSource(url, options);
/**
* options:Object 类型,表示可选参数。常用的可选参数包括:
withCredentials:Boolean 类型,表示是否允许发送 Cookie 和 HTTP 认证信息。默认为 false。
headers:Object 类型,表示要发送的请求头信息。
retryInterval:Number 类型,表示与服务器失去连接后,重新连接的时间间隔。默认为 1000 毫秒。
*
* */
eventSource.onopen = function(event) {
console.log('连接成功!', event);
};
eventSource.onmessage = function(event) {
console.log('接收到数据:', event);
};
eventSource.onerror = function(event) {
console.log('发生错误:', event);
};
// close() 方法用于关闭 EventSource 对象与服务器的连接,停止接收服务器发送的数据。
eventSource.close();
TIP
转发 SSE 请求的nginx配置
location ~ ^/sse/ { # 匹配以 /sse/ 开头的路径
proxy_pass http://127.0.0.1:8000; # 转发到ASGI 后端服务
proxy_http_version 1.1; # 强制使用 HTTP 1.1,以支持持久连接。
proxy_set_header Connection '';
proxy_buffering off; # 禁用缓冲,确保实时性
proxy_read_timeout 3600s; # 设置超时时间
}
WebSocket
WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
WebSocket 本质上一种计算机网络应用层的协议,用来弥补 http 协议在持久通信能力上的不足。
(1)建立在 TCP 协议之上,服务器端的实现比较容易。 (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。 (3)数据格式比较轻量,性能开销小,通信高效。 (4)可以发送文本,也可以发送二进制数据。 (5)没有同源限制,客户端可以与任意服务器通信。 (6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。
js
const socket = newWebSocket('ws://example.com:80/some/path' [, protocols]);
socket.onopen = function(event) {
console.log(`socket on open from server: ${event}`);
};
// 发送信息
socket.send(chat.value);
// 接收信息
socket.onmessage = function(event) {
console.log(`Data received from server: ${event.data}`);
let response:Resp = JSON.parse(event.data);
};
socket.onerror = function(error) {
console.error(`WebSocket Error: ${error}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log('Closed cleanly, code:', event.code, 'reason:', event.reason);
} else {
console.error('Connection died');
}
};
// 主动断开连接
socket.close();
TIP
转发 WebSocket 请求 nginx配置
location ^~ /ws/ {
proxy_pass http://127.0.0.1:8000; # 转发到 ASGI 服务器
# 保证连接不会超时
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# 转发 WebSocket 请求头
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 特有配置
proxy_http_version 1.1;
# 确保请求头包含 Upgrade 和 Connection 字段,以支持 WebSocket 协议。
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 可选: 传递 Authorization 头部,如果需要身份验证
proxy_set_header Authorization $http_authorization;
}
区别
SSE | WebSocket | |
---|---|---|
通信方向 | 单向通信(服务器到客户端) | 双向通信(服务器到客户端,客户端到服务器) |
协议 | HTTP 协议 | WebSocket 协议(初始握手通过 HTTP 升级) |
数据格式 | 仅支持文本数据,通常使用 UTF-8 编码 | 支持文本和二进制数据 |
自动重连 | 浏览器原生支持自动重连 | 手动实现重连逻辑 |
跨域支持 | 同源策略限制,需要 CORS 支持 | 天生支持跨域 |