SSE服务器到客户端单向推送
目录一、使用场景以及与websocket的区别二、SSEServer-Sent Events数据推送机制1. 推送原理2. 前端接收方式3. 数据流向三、实际应用示例1.SSE后端推送数据四、注意事项 EventSource构造函数参数说明1.参数含义2.参数要求3.示例五、服务器端接口要求1.响应头设置2.数据格式3.示例响应4.CORS配置5.前后端代码示例一、使用场景以及与websocket的区别SSEwebsocket选型建议只要服务端推送行情、通知、日志→ 优先 SSE简单、纯 HTTP、天然兼容 HTTP/2 多路复用需要双向频繁通信聊天、协同、游戏→ WebSocket不要为了实时硬上 WebSocketSSE 能搞定的就 SSE运维成本低一档二、SSEServer-Sent Events数据推送机制1. 推送原理服务器→客户端单向推送SSE基于HTTP协议通过长连接实现服务器主动向客户端推送数据。数据格式服务器发送的数据必须符合特定格式data: 内容\n\ndata:是默认事件名可通过event: 自定义事件名指定。持久连接服务器保持连接打开客户端通过EventSource对象接收数据。2. 前端接收方式// 1. 创建EventSource实例连接服务器consteventSourcenewEventSource(/sse/events);// 2. 监听默认的message事件接收服务器推送的数据eventSource.onmessagefunction(event){console.log(收到数据:,event.data);// 数据被推送到这里// 可以更新DOM、触发业务逻辑等};// 3. 监听自定义事件如服务器发送的update事件eventSource.addEventListener(update,function(event){console.log(收到更新事件:,event.data);});3. 数据流向服务器 →HTTP响应流 → 浏览器EventSource解析 → onmessage事件 → 前端处理三、实际应用示例1.SSE后端推送数据// Node.js后端Expressapp.get(/sse/events,(req,res){res.setHeader(Content-Type,text/event-stream);res.setHeader(Cache-Control,no-cache);// 模拟实时数据推送每秒发送一次setInterval((){res.write(data:${newDate().toISOString()}\n\n);},1000);});四、注意事项 EventSource构造函数参数说明1.参数含义URL服务器端提供SSE事件流的接口地址可以是相对路径如/sse/events或绝对路径如http://localhost:3000/sse/events必须是HTTP或HTTPS协议的URL2.参数要求consteventSourcenewEventSource(url,[options]);url必需服务器端SSE接口地址options可选配置对象常用属性{withCredentials:true// 是否携带跨域凭据如cookies}3.示例// 相对路径同源请求consteventSourcenewEventSource(/sse/events);// 绝对路径跨域请求consteventSourcenewEventSource(https://api.example.com/sse/events,{withCredentials:true// 携带跨域凭据});五、服务器端接口要求1.响应头设置服务器端必须返回特定的响应头Content-Type:text/event-streamCache-Control:no-cacheConnection:keep-alive2.数据格式服务器发送的数据必须符合SSE格式data:事件数据\n\n// 基本格式id:消息ID\n// 可选用于重连定位event:事件名\n// 可选自定义事件名retry:5000\n// 可选重连间隔毫秒3.示例响应data:{message:Hello SSE!}\n\n id:12345\n event:update\n data:{status:online}\n\n4.CORS配置如果接口是跨域的服务器端需要设置CORS头Access-Control-Allow-Origin:*Access-Control-Allow-Credentials:true5.前后端代码示例前端代码consteventSourcenewEventSource(/sse/events);eventSource.onmessagefunction(event){console.log(收到数据:,event.data);};eventSource.onerrorfunction(error){console.error(连接错误:,error);if(eventSource.readyStateEventSource.CLOSED){// 可以尝试重新连接setTimeout((){eventSourcenewEventSource(/sse/events);},5000);}};后端代码node.jsapp.get(/sse/events,(req,res){res.setHeader(Content-Type,text/event-stream);res.setHeader(Cache-Control,no-cache);// 定时推送数据setInterval((){res.write(data:${JSON.stringify({time:newDate().toISOString()})}\n\n);},1000);});