来源 http://www.ruanyifeng.com/blog/2017/05/server-sent_events.html
HTTP 无法做到服务端主动推送消息,但是有一种变通方法,就是服务器向客户端生命,接下来要发送的是流信息(streaming)
也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断的发送过来,这时候客户端不会关闭连接,会等待服务器发送来的新的数据流,视频播放就是这样的例子。本质上,这种通信就是一流信息的方式,完成一次用时很长的下载。
客户端
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <div id="example"></div> <script> var source = new EventSource('http://127.0.0.1:8844/stream'); var div = document.getElementById('example'); source.onopen = function (event) { div.innerHTML += '<p>Connection open ...</p>'; }; source.onerror = function (event) { div.innerHTML += '<p>Connection close.</p>'; }; source.addEventListener('connecttime', function (event) { div.innerHTML += ('<p>Start time: ' + event.data + '</p>'); }, false); source.onmessage = function (event) { div.innerHTML += ('<p>Ping: ' + event.data + '</p>'); }; </script> </body> </html>
服务端 Node.js 实现
var http = require("http"); http.createServer(function (req, res) { var fileName = "." + req.url; if (fileName === "./stream") { res.writeHead(200, { "Content-Type":"text/event-stream", "Cache-Control":"no-cache", "Connection":"keep-alive", "Access-Control-Allow-Origin": '*', }); res.write("retry: 10000 "); res.write("event: connecttime "); res.write("data: " + (new Date()) + " "); res.write("data: " + (new Date()) + " "); interval = setInterval(function () { res.write("data: " + (new Date()) + " "); }, 1000); req.connection.addListener("close", function () { clearInterval(interval); }, false); } }).listen(8844, "0.0.0.0");