事件流请求未在乘客apache下触发关闭事件

时间:2014-06-03 14:25:46

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

所以我在快速js节点应用程序中有一个事件流。这是一个概述:

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

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

干杯, 丹

1 个答案:

答案 0 :(得分:3)

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

这是一个很长的答案。如果客户端直接连接到Node.js进程,则是,连接已关闭。但是对于Phusion Passenger,客户端和Node.js之间存在代理。关于套接字的事情是有两种方法可以找出套接字是否已经关闭:1)通过从中读取文件结尾,或2)通过写入并获得错误。 Phusion Passenger一旦确定请求正文已经结束,就会停止从客户端读取。在GET请求的情况下,这是在标题之后。因此,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及更高版本,它就会按预期工作。