后端数据推送-EventSource
服务器发送事件(以下简称SSE)是HTML 5规范的一个组成部分,可以实现服务器到客户端的单向数据通信。通过SSE,客户端可以自动获取数据更新,而不用重复发送HTTP请求。一旦连接建立,“事件”便会自动被推送到客户端。服务器端SSE通过“事件流(Event Stream)”的格式产生并推送事件。事件流对应的MIME类型为“text/event-stream”,包含四个字段:event、data、id和retry。event表示事件类型,data表示消息内容,id用于设置客户端EventSource对象的“last event ID string”内部属性,retry指定了重新连接的时间。
node代码示例:
前端部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var evtSource = new EventSource( "http://localhost:3000" ); let eventList = document.getElementsByTagName( 'body' )[0] // evtSource.onmessage = function(e) { // console.log(1111,e); // var newElement = document.createElement("li"); // const eventList = document.getElementsByTagName('body')[0] // // console.log(eventList); // newElement.innerHTML = "message: " + e.data; // eventList.appendChild(newElement); // } evtSource.addEventListener( "ping" , function(e) { console.log(2222,e); var newElement = document.createElement( "li" ); let eventList = document.getElementsByTagName( 'body' )[0] var obj = JSON.parse(e.data); newElement.innerHTML = "ping at " + obj.date; eventList.appendChild(newElement); }, false ); evtSource.addEventListener( "error" ,function(e){ console.log( "服务器发送给客户端的数据为:" + e.data); }); //只要和服务器连接,就会触发open事件 evtSource.addEventListener( "open" ,function(){ console.log( "和服务器建立连接" ); }); //处理服务器响应报文中的load事件 evtSource.addEventListener( "load" ,function(e){ console.log( "服务器发送给客户端的数据为:" + e.data); }); |
服务端部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const http = require( 'http' ) http.createServer((req, res) => { res.writeHead(200, { 'Content-Type' : 'text/event-stream' , 'Access-Control-Allow-Origin' : '*' }) let i = 0; const timer = setInterval(()=>{ const date = {date: new Date()} var content = 'event: ping\n' + "data:" +JSON.stringify(date)+ "" + "\n\n" ; res.write(content); },1000) res.connection. on ( "close" , function(){ res.end(); clearInterval(timer); console.log( "Client closed connection. Aborting." ); }); }).listen(3000) console.log( 'server is run http://localhost:3000' ); |
java的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //媒体类型为 text/event-stream response.setContentType( "text/event-stream" ); response.setCharacterEncoding( "utf-8" ); PrintWriter out = response.getWriter(); //响应报文格式为: //data:Hello World //event:load //id:140312 //换行符(/r/n) out .println( "data:Hello World" ); out .println( "event:load" ); out .println( "id:140312" ); out .println(); out .flush(); out .close(); } |
SSE相较于轮询具有较好的实时性,使用方法也非常简便。然而SSE只支持服务器到客户端单向的事件推送,而且所有版本的IE(包括到目前为止的Microsoft Edge)都不支持SSE。如果需要强行支持IE和部分移动端浏览器,可以尝试EventSource Polyfill(本质上仍然是轮询)
参考文章:
https://developer.mozilla.org/zh-CN/docs/Server-sent_events/Using_server-sent_events
你要觉得这篇文章比较好,记得点推荐!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通