升级 SSE 🌐
SSE 简介
Server-Sent Events (SSE) 是一种基于HTTP协议的服务器推送技术,它允许服务器向客户端发送事件流。与WebSocket不同,SSE是单向通信机制,专注于服务器到客户端的数据推送。
SSE 特点
- 单向通信:服务器向客户端推送数据,不支持客户端发送数据
- 基于HTTP:无需额外协议,复用HTTP连接
- 自动重连:浏览器原生支持断线重连
- 消息格式化:支持事件类型、ID和数据的结构化传输
SSE 工作原理
上图展示了SSE的工作原理:服务器通过HTTP连接向客户端建立单向的事件流通道,客户端使用EventSource API接收服务器推送的实时数据。
适用场景
- 实时数据流更新(如股票行情、比赛比分)
- AI大语言模型流式输出
- 系统通知和实时提醒
- 日志实时监控
- 进度状态更新
Feat框架中的SSE实现
服务端实现
在Feat框架中使用SSE非常简单,只需通过SSEUpgrade
类来处理SSE连接:
public class SSEDemo { public static void main(String[] args) throws Exception { Feat.httpServer(serverOptions -> serverOptions.debug(true)).httpHandler(req -> { req.upgrade(new SSEUpgrade() { public void onOpen(SseEmitter sseEmitter) { // 创建定时任务,每秒发送一条消息 Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { try { sseEmitter.send(SseEmitter.event() .name("update") // 设置事件名称 .id(String.valueOf(i++)) // 设置事件ID .data("hello world")); // 设置事件数据 } catch (IOException e) { throw new RuntimeException(e); } }, 1, 1, TimeUnit.SECONDS); } }); }).listen(8080); }}
客户端实现
在浏览器端,使用标准的EventSource
API来接收SSE事件:
// 创建EventSource实例const eventSource = new EventSource('/sse-endpoint');
// 监听指定类型的事件eventSource.addEventListener('update', (event) => { console.log('收到更新:', event.data); console.log('事件ID:', event.lastEventId);});
// 监听连接打开eventSource.onopen = () => { console.log('SSE连接已建立');};
// 监听错误eventSource.onerror = (error) => { console.error('SSE连接错误:', error);};
注意事项
- SSE连接数限制:浏览器对同一域名的SSE连接数有限制,通常为6个
- 超时处理:建议在服务端定期发送心跳消息保持连接
- 错误处理:实现完善的错误处理机制,包括重连策略
- 资源释放:不再需要SSE连接时,调用
eventSource.close()
关闭连接 - 跨域支持:服务端需要正确配置CORS头信息
最佳实践
- 合理使用事件类型:通过event字段区分不同类型的消息
- 消息去重:利用事件ID实现消息去重和断点续传
- 数据压缩:对大量数据考虑使用压缩算法
- 连接管理:实现连接池管理,避免资源泄露
- 监控告警:对SSE连接状态进行监控,及时发现异常