H5Server Sent Event服务端主动发送数据回客户端

效果图

这里写图片描述

Server Sent Event

Server Sent Event通过EventSource对象接收服务器发送事件的通知. 有三个事件message, open, error

下面的代码演示了使用的方法

例子代码运行环境: node.js

代码

粘贴下面代码运行node index.js

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>server-sent</title>
</head>
<body>
<script>
window.addEventListener("load",function () {
let status = document.getElementById("status");
let output = document.getElementById("output");
let source;
function connect() {
source = new EventSource("stream");//与服务器端建立连接
//鉴定message事件, 获取服务端发送的数据
source.addEventListener("message", function (event) {
output.textContent = event.data;
}, false);
//监听open事件, 判断连接是否进行中
source,addEventListener("open", function (event) {
status.textContent = '连接打开了';
},false);
//监听error事件, 处理连接错误的情况
source.addEventListener("error", function (event) {
if (event.target.readyState === EventSource.CLOSED) {
source.close();
status.textContent = '连接关闭了';
} else {
status.textContent = "连接关闭了!未知错误!";
}
}, false);
}
if(!!window.EventSource) {
connect();
} else {
status.textContent = "不支持server-sent"
}
},false);
</script>
<span id="status">Connection closed!</span>
<br>
<span id="output"></span>
</body>
</html>

服务端代码

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//index.js
const http = require('http');
const fs = require('fs');
http.createServer(function (req, res) {
let interval,
fileName,
index = "./index.html";
console.log(req.url);
if(req.url === "/") {
fileName = index;
} else {
fileName = "." + req.url;
}
if (fileName === "./stream") {//如果server sent event则设置相应头信息
res.writeHead(200, {
"Content-Type" : "text/event-stream",
"Cache-Control" : "no-cache",
"Connection": "keep-alive",
})
res.write("retry: 10000\n");//过10000秒重试
res.write("data: " + (new Date()) + "\n\n");
interval = setInterval(function () {
res.write("data: " + (new Date()) + "\n\n");
}, 1000);
//监听close事件, 用于停止定时器
req.connection.addListener("close", function () {
clearInterval(interval);
}, false);
} else if (fileName === index) {
//判断是否为页面请求, 并找到相应文件返回页面
fs.exists(fileName, function (exists) {
if (exists) {
fs.readFile(fileName, function (error, content) {
if (error) {
res.writeHead(500);
res.end();
} else {
res.writeHead(200, {"Content-Type" : "text/html"});
res.end(content, "utf-8");
}
})
} else {
console.log(123);
res.writeHead(404);
res.end();
}
})
} else {
res.writeHead(404);
res.end();
}
}).listen(8080, "127.0.0.1");
console.log("at 8080");

越来越多的平台(微信公众平台,新浪微博,简书,百度打赏等)支持打赏功能,付费阅读时代越来越近,特此增加了打赏功能,支持微信打赏和支付宝打赏。坚持原创技术分享,您的支持将鼓励我继续创作!