sse 与 fetch post 组合可实现轻量级“类双向”通信:sse 单向接收服务端推送,fetch post 独立发起客户端请求,通过 token 关联两者,服务端据此精准推送事件。

JavaScript 中 SSE(Server-Sent Events)本身是单向(服务端→客户端)的,无法直接发送数据回服务端。但通过搭配 Fetch POST(或其它 HTTP 请求),可以在逻辑上构建“类双向”交互,且比 WebSocket 更轻量、兼容性更好、无需额外长连接维护。
用 SSE 接收实时更新,Fetch POST 发起主动请求
SSE 负责持续监听服务端推送(如通知、状态变更、日志流),Fetch POST 则用于客户端需要触发动作时(如提交表单、确认操作、上报事件)。两者职责分离,互不干扰。
- SSE 连接保持常开(自动重连机制可由浏览器内置或手动实现),只消耗一个 HTTP 连接
- 每次 Fetch POST 都是独立短连接,用完即关,无连接复用负担
- 服务端无需维护会话状态(如不用存 socket ID),只需响应 POST 并按规则向对应 SSE 流写入事件
关键:为每个客户端建立唯一标识并关联 SSE 流
服务端需识别“哪个 POST 请求对应哪个 SSE 客户端”,否则无法精准推送。常见做法是:
- 前端首次建立 SSE 时,服务端生成一个临时 token(如 UUID),返回给前端(可通过 initial event 或额外接口获取)
- 后续所有 Fetch POST 都带上该 token(如放在 URL query、header 或 body 中)
- 服务端根据 token 找到对应的 SSE 响应流(例如存在 Map
中),向其写入 event: xxx\ndata: {...}\n\n
注意:token 不必长期有效,可设 TTL(如 10 分钟),配合 SSE 的 reconnect 时间(retry: 3000)即可平滑续期。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
前端代码示例(简洁可运行)
以下是一个典型组合用法:
// 1. 启动 SSE,获取并保存 token
let eventSource;
async function startSSE() {
const res = await fetch('/api/sse-init');
const { token } = await res.json();
eventSource = new EventSource(`/api/stream?token=${token}`);
eventSource.onmessage = e => console.log('收到推送:', JSON.parse(e.data));
eventSource.onerror = () => console.warn('SSE 断开,将自动重连');
}
// 2. 需要“发消息”时,用 Fetch POST + token
async function sendAction(payload) {
await fetch('/api/action', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...payload, token: getStoredToken() })
});
}
// 3. 启动
startSSE();
适用场景与避坑提醒
这种模式适合“读多写少、实时性要求中等、希望降低部署复杂度”的场景,比如后台管理系统的任务状态看板、低频协作编辑、IoT 设备状态轮询替代方案。
- ❌ 不适合高频双向通信(如聊天、协同光标),此时 WebSocket 更合适
- ✅ 可配合 Service Worker 实现离线 POST 缓存 + 网络恢复后重发
- ✅ SSE 响应头必须含 Content-Type: text/event-stream,且不能关闭 response 流(否则连接断开)
- ✅ Fetch POST 应设 timeout,避免阻塞 UI;失败时建议降级为轮询或提示重试
不复杂但容易忽略细节:token 传递一致性、SSE 连接生命周期管理、服务端流写入的并发安全(如用 async iterator 或锁机制防 write 冲突)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










