【发布时间】:2019-11-25 13:06:03
【问题描述】:
我希望使用 SSE 向浏览器动态发送消息。理想情况下,我想要一个最小的应用程序,其中浏览器在调用函数或方法(将消息作为参数)之前什么都不做,并且浏览器收到此消息并仅记录一次。我试图用以下来说明这一点:
const http = require("http");
const server = http.createServer(<not sure what code goes here>);
server.listen(8000);
// this can be called at any time after creating the server so the browser
// can receive the message and log it to the console.
sendMessageToBrowser(`data: this is a dynamic message\n\n`)
但是,下面的基本 SSE 应用程序只是每 3 秒(默认)将“hello world”记录到浏览器控制台。我不明白这与通过常规路线提供数据并使用类似的方式有什么不同:
setInterval(fetch("/events").then(res => res.text()).then(data => console.log(data)));
我的请求是否可以通过 SSE 提出,还是我误解了它的工作原理?我知道我的请求可以通过 websockets/socket.io 实现,但我希望使用 SSE,因为我不想使用更易于理解和实现的库和 SSE。
每 3 秒记录一次 hello world 的最小示例:
const http = require("http");
const server = http.createServer((req, res) => {
// Server-sent events endpoint
if (req.url === "/events") {
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
res.end(`data: hello world\n\n`);
return;
}
// Client side logs message data to console
res.writeHead(200, { "Content-Type": "text/html" });
res.end(`
<script>
var eventSource = new EventSource('/events');
eventSource.onmessage = function(event) {
console.log(event.data);
};
</script>
`);
});
server.listen(8000);
【问题讨论】:
-
发生的事情是它只是每 3 秒重新连接一次,检查您的网络选项卡,SSE 应该循环服务器端的原因,因此连接挂起直到数据输出,您的
res.end将结束连接,忽略任何保持活动状态.. 我没有在 nodejs 中实现 SSE,socketio 太容易了,但是如果您要移植,也许一个 php 示例会有所帮助。 stackoverflow.com/a/49081040/661872 -
你可以使用Socket.io作为后端来监听前端的事件你可以使用Socket.io-client
-
@LawrenceCherone 感谢您提供的信息。我已将 res.end() 更改为 res.write() 所以消息只发送到浏览器一次。但是,我仍然看不到如何从服务器发送其他消息。我认为 SSE 的全部意义在于,在发生某些服务器端事件时,我可以向浏览器发送新消息?
-
你可以例如:
setInterval(),也许是 eventemitter,或者通过数据库行和一个循环代理,在里面轮询事件 id 的变化,没有像 socketio 这样的发射概念 -
“没有像socketio一样发射的概念”这是关键。回想起来,我的问题应该只是:“SSE 的 socket.io 的 socket.emit() 是什么?”答案似乎是没有。不过我觉得这很奇怪,因为我读过的所有内容都将 SSE 描述为 websocket 的单向等价物,并且顾名思义,可以使用服务器端事件来发出消息。
标签: javascript node.js websocket server-sent-events