Skip to content

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;
}

区别

SSEWebSocket
通信方向单向通信(服务器到客户端)双向通信(服务器到客户端,客户端到服务器)
协议HTTP 协议WebSocket 协议(初始握手通过 HTTP 升级)
数据格式仅支持文本数据,通常使用 UTF-8 编码支持文本和二进制数据
自动重连浏览器原生支持自动重连手动实现重连逻辑
跨域支持同源策略限制,需要 CORS 支持天生支持跨域