触发Express JS中的事件以便另一个处理程序监听的方法是什么?

huangapple go评论55阅读模式
英文:

How do I trigger events from a handler so that another handler can listen to it in Express JS

问题

我正在构建一个Web应用程序,其中当有人发布帖子时,所有订阅者都会收到通知。我在Node.js中使用SSE(服务器发送事件)。我的示例代码如下。

postEvent.js

const EventEmitter = require("node:events");
class PostEvent extends EventEmitter {}
module.exports = new PostEvent();

post.js

const PostEvent = require('./postEvent');
app.post('/post', (req, res) => {
   // 从req获取数据并保存到数据库
  PostEvent.emit('posted');
})

sse.js

const PostEvent = require('./postEvent');
app.get('/sse', (req, res) => {
   res.set('Content-Type', 'text/event-stream'); // 用于无限流式传输服务器响应
   setInterval(() => res.write('data: 每秒的SSE数据\n\n'), 1000); // 这部分有效
   PostEvent.on('posted', () => res.write('data: 已发布\n\n')); // 这部分无效
})

问题在于 PostEvent.on('posted', callback) 在我向 /post 路由发送fetch请求时不会运行。我是做错了什么还是事件系统不像这样工作?有什么其他方法可以实现这个功能吗?

注意: 未提到Express的样板代码,客户端部分在发送流时使用 EventSource 正常工作。

编辑: 我们是否可以在http或sse环境中使用此事件系统?我没有向/sse发出请求,但我正在尝试在其中运行该函数。

英文:

I'm building a web app wherein when someone posts a post, all subscribers receive a notification. I'm using SSE (server sent events) in Node js. My example code looks like this.

postEvent.js

const EventEmitter = require("node:events");
class PostEvent extends EventEmitter {}
module.exports = new PostEvent();

post.js

const PostEvent = require('./postEvent');
app.post('/post', (req, res) => {
   // get data from req and save to the database
  PostEvent.emit('posted');
})

sse.js

const PostEvent = require('./postEvent');
app.get('/sse', (req, res) => {
   res.set('Content-Type', 'text/event-stream'); // for streaming server response indefinitely
   setInterval(() => res.write(`data: my sse data every second\n\n`), 1000); // this works
   PostEvent.on('posted', () => res.write('data: posted\n\n')); // this doesn't
})

The problem here is that the PostEvent.on('posted', callback) doesn't run when I send a fetch request to the /post route. Am I doing something wrong or the event system doesn't work like this?
Is there anything else that I can do to implement this functionality?

Note: Express boilerplate code has not been mentioned and the client side functions properly with EventSource when streams are sent.

Edit: Can we do this event system in an http or sse environment at all? I'm not making a request to /sse, but I'm trying to run the function in it.

答案1

得分: 1

以下是您要翻译的内容:

"我无法在只使用一个文件来处理两个路由时重现您的问题:https://prnt.sc/sOzp0xHvpbDM

我猜测,当将它拆分为两个文件(post.js 和 sse.js)时,不同的 PostEvent 实例正在传递。如果是这种情况,那么您需要实例化然后在两个位置都传递相同的实例。

const express = require("express");
const PostEvent = require('./postEvent');

const app = express();

app.post('/post', (req, res) => {
  PostEvent.emit('posted');
  res.json("事件已发布");
})

app.get('/sse', (req, res) => {
  res.set('Content-Type', 'text/event-stream');
  setInterval(() => res.write(`data: 每秒我的 SSE 数据\n\n`), 1000);
  PostEvent.on('posted', () => res.write(`data: 在 ${new Date().toLocaleTimeString()} 发布\n\n`));
})

const PORT = 3000;
app.listen(PORT, function (err) {
  if (err) console.log(err);
  console.log("服务器监听端口", PORT);
});

希望这对您有所帮助。

英文:

I was not able to reproduce your problem when using only one file for both routes: https://prnt.sc/sOzp0xHvpbDM

My bet is that when having it split in 2 files (post.js and sse.js) different instances of the PostEvent are being passed. If that is the case then you will need to instantiate and then pass the same in both spots.

const express = require("express");
const PostEvent = require('./postEvent');

const app = express();

app.post('/post', (req, res) => {
  PostEvent.emit('posted');
  res.json("event posted");
})

app.get('/sse', (req, res) => {
  res.set('Content-Type', 'text/event-stream');
  setInterval(() => res.write(`data: my sse data every second\n\n`), 1000);
  PostEvent.on('posted', () => res.write(`data: posted in ${new Date().toLocaleTimeString()} \n\n`));
})

const PORT = 3000;
app.listen(PORT, function (err) {
  if (err) console.log(err);
  console.log("Server listening on PORT", PORT);
});

huangapple
  • 本文由 发表于 2023年6月8日 23:31:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定