JavaScript 如何接收服务器发送的事件通知
这是一种通过与服务器建立持久连接进行的单向通信。客户端首先与服务器建立连接,并等待服务器触发事件,服务器通过向客户端发送一些消息来触发事件。
现在,我们将学习如何通过服务器发送的事件(简称 SSE )从服务器接收通知。
对于这个任务,我们需要使用两个不同的角度:
- 客户端: 建立连接
- 服务器: 接受客户端请求
在客户端上,我们创建一个HTML页面,并使用 EventSource类 向服务器发起异步请求。
EventSource 类与服务器建立持久连接,并提供一种监听服务器事件的方法。
我们需要创建这个类的一个实例,例如:
语法:
var sse = new EventSource("url");
其中,
- sse 是 EventSource 对象
用于监听服务器消息的方法是
message 。
语法:
sse.onmessage = (event)=>{
...
}
在服务器端,我使用 express 和 nodejs 来监听客户端的请求,但你可以选择你喜欢的服务器端语言。
语法:
var express = require("express");
var app = express();
app.get('/events', async function(req, res) {
res.set({
'Cache-Control': 'no-cache',
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin':'*'
});
res.flushHeaders();
res.write('hi');
}
app.listen(3000);
在上面的代码中,我们监听的端口是3000,并且监听某个URL路径。 请确保使用以下HTTP头部使连接保持持久性: ‘Connection’: ‘keep-alive’ 并将响应类型设置为event-stream: ‘Content-Type’: ‘text/event-stream’ 浏览器实现了CORS,所以请指定以下HTTP头部: ‘Access-Control-Allow-Origin’:’*’ 使用res对象向客户端发送通知。
示例:
在下面的示例中,我们将连接到“http://localhost:3000/events”,并在控制台标签上打印服务器消息。在服务器端,我们将使用express的GET方法监听“/events”URL。 在服务器端的代码中,我们创建一个名为run的函数,用于注册监听函数,并使用res对象向EventSource实例发送消息。 服务器会发送消息,该消息是每秒钟递增的计数器的值。
客户端代码:
<html>
<body>
<script type="text/javascript">
const source = new EventSource('http://localhost:3000/events');
source.addEventListener('message', message => {
console.log('Got', message);
});
</script>
</body>
</html>
输出:

- 服务器端代码:
JavaScript
'use strict';
const express = require('express');
run().catch(err => console.log(err));
async function run() {
const app = express();
app.get('/events', async function (req, res) {
console.log('Got /events');
res.set({
'Cache-Control': 'no-cache',
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*'
});
res.flushHeaders();
// Tell the client to retry every 10 seconds
// if connectivity is lost
res.write('retry: 1000 \n\n');
let count = 0;
while (true) {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Emit', ++count);
// Emit an SSE that contains the current
// 'count' as a string
res.write(`data: ${count}\n\n`);
}
});
await app.listen(3000);
console.log('Listening on port 3000');
}
输出: 输出表示数据的发射,这是一个每秒计数的计数器。

极客教程