javascript - 事件流请求未在 passenger apache 下触发关闭事件

标签 javascript node.js express passenger server-sent-events

所以我的 express js Node 应用程序中有一个事件流。这是一个概述:

app.get('/eventstream', function(req, res){

    req.socket.setTimeout(Infinity);

    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    res.write('/n');

    req.on('close', function(){
        console.log('connection closed');
    });

}

在我的本地开发箱上,从命令行运行

node app.js

它工作正常,并在我关闭浏览器中的选项卡时打印出“连接已关闭”。 但是,当在我的服务器上运行时,在 Apache with Passenger 下,它不会打印出任何消息——服务器似乎没有触发“关闭”事件。我正在使用此事件从我的活跃用户数中删除。有什么想法吗?

干杯, 丹

最佳答案

Phusion Passenger 作者在这里。简短的回答是:从技术上讲,连接尚未关闭。

这是长答案。如果客户端直接连接到您的 Node.js 进程,那么是的,连接已关闭。但是对于 Phusion Passenger,在客户端和 Node.js 之间有一个代理。关于套接字的事情是,有两种方法可以查明套接字是否已关闭:1)通过从中读取文件结尾,或 2)通过写入它并收到错误。 Phusion Passenger 在确定请求正文结束后立即停止从客户端读取。在 GET 请求的情况下,它紧跟在 header 之后。因此,Phusion Passenger 可以注意到客户端已关闭连接的唯一方法是向其发送数据。但是您的应用程序永远不会在该换行符之后发送任何数据,因此 Phusion Passenger 也不会这样做并且永远不会注意到连接已关闭。

此问题不限于 Phusion Passenger。如果您将 Node.js 应用放在负载均衡器或任何其他类型的反向代理后面,那么您也可能会遇到同样的问题。

标准的解决方案是定期发送“ping”消息,目的是检查连接是否存活。

A similar issue also applies to WebSockets.这就是 WebSocket 支持 ping 帧的原因。

2016 年 2 月 28 日更新:

我们找到了解决方案,Passenger 5.0.26 及更高版本支持转发半关闭事件,解决了@coffeedougnuts 描述的问题。只需使用 5.0.26 及更高版本,它就会按预期工作。

关于javascript - 事件流请求未在 passenger apache 下触发关闭事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24017770/

相关文章:

node.js - Sequelize 返回未定义

javascript - 使用 react 更改列表中的事件元素

javascript - 如何让正则表达式在某个字符处停止

javascript - Node/Electron : Convert one timezone to the other in website/client side

javascript - 在连接的 DynamoDB 表中传播更改的正确方法是什么

node.js - 应用程序所有者获得错误的访问 token

javascript - 返回 404 的 Express 路线

firebase - 在 Firebase Cloud 函数中获取请求 URL

javascript - 我怎样才能改变这个时钟的速度

javascript - 更改可配置产品的价格