Node.JS服务器发送事件:res.end()之后,路由继续运行,导致ERR_STREAM_WRITE_AFTER_END错误

问题描述 投票:0回答:1

由于我的Web应用程序需要从服务器接收实时更新,因此我开始使用服务器发送事件(SSE)。它不需要发送任何内容到服务器,因此通过Websockets选择了SSE。

在阅读了一些示例之后,我有以下代码:

在我的服务器上,在./ src / routers / mainRouter.js中,我有:

router.get('/updates', (req, res) => {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    })

    // Listens for 'event' and sends an 'Event triggered!' message to client when its heard.
    eventEmitter.addListener('event', () => {
        console.log('Event triggered! Sending response.')
        res.write('data: Event triggered!\n\n')
    })

    req.on('close', () => {
        console.log('Connection to client closed.')
        res.end()
    })
})

module.exports = router

在我的客户端上,在[[./app/index.js中,我有:

const source = new EventSource('/updates') source.onmessage = (e) => { console.log(e) }
我有两个问题:

  1. 一旦从客户端打开连接,然后关闭连接(通过关闭选项卡),'close'事件触发两次导致req.on('close')中的代码块运行两次。我不确定为什么会这样。我在服务器端的console看起来如下:

    Event triggered! Sending response. Connection to client closed. Connection to client closed.

  • 更重要的是,尽管调用了req.end(),但路由器仍然继续监听该频道上的事件并尝试发送沿着该渠道做出回应,导致ERR_STREAM_WRITE_AFTER_END错误和服务器崩溃。所以最终控制台输出看起来像:

    Event triggered! Sending response. // First event triggers. Connection to client closed. // 'close' event fires. Connection to client closed. // 'close' event fires a second time (not sure why). Event triggered! Sending response. // Router continues listening for 'event' and sends another response although res.end() was called earlier events.js:187 throw er; // Unhandled 'error' event ^ Error [ERR_STREAM_WRITE_AFTER_END]: write after end

  • node.js google-chrome server-sent-events
    1个回答
    0
    投票
    当流关闭时,您需要删除事件监听器,这样您就不会尝试再次写入流。可以这样做:

    router.get('/updates', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); function listener(event) { console.log('Event triggered! Sending response.'); res.write('data: Event triggered!\n\n'); } // Listens for 'event' and sends an 'Event triggered!' message to client when its heard. eventEmitter.addListener('event', listener); req.on('close', () => { // remove listener so it won't try to write to this stream any more eventEmitter.removeListener('event', listener); console.log('Connection to client closed.'); res.end(); }); }); module.exports = router;

    © www.soinside.com 2019 - 2024. All rights reserved.