服务器发送事件(以下简称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代码示例:
前端部分
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); });
服务端部分
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的示例
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
原文:https://www.cnblogs.com/yiyi17/p/11486125.html