事件stream请求不发射客运阿帕奇下的closures事件

所以我在我的express js节点应用程序中有一个事件stream。 这里有一个概述:

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 

它工作正常,并打印出“连接closures”,当我closures我的浏览器中的标签。 但是,在我的服务器上运行,在Passenger的Apache下,它不会打印出任何消息 – 服务器似乎不会触发“closures”事件。 我正在使用此事件从我的活跃用户数中删除。 有任何想法吗?

干杯,丹

Phusion旅客作者在这里。 简而言之,在技术上,连接还没有closures。

这是很长的答案。 如果客户端直接连接到Node.js进程,那么是的,连接就closures了。 但是在Phusion Passenger中,客户端和Node.js之间有一个代理。 关于套接字的事情是有两种方法来确定一个套接字是否被closures了:或者1)通过读取文件的结尾,或者2)通过写入来获得一个错误。 一旦确定请求主体已经结束,Phusion Passenger立即停止从客户那里读取数据。 而在GET请求的情况下,这是紧跟在标题之后。 因此,Phusion Passenger可以注意到客户已经closures连接的唯一方法就是向它发送数据。 但是你的应用程序不会在换行之后发送任何数据,所以Phusion Passenger也不会这么做,也从不知道连接是closures的。

这个问题不仅限于Phusion Passenger。 如果您将Node.js应用程序放在负载平衡器或任何其他types的反向代理之后,那么您也可能遇到同样的问题。

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

类似的问题也适用于WebSockets。 这是WebSocket支持ping帧的原因。

更新2016年2月28日:

我们已经find了一个解决scheme,Passenger 5.0.26和更高版本支持转发半closures事件,修复@coffeedougnuts描述的问题。 只要使用5.0.26及更高版本,它将按预期工作。