【问题标题】:event stream request not firing close event under passenger apache事件流请求未在乘客 apache 下触发关闭事件
【发布时间】:2014-06-03 14:25:45
【问题描述】:

所以我的 express 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

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

干杯, 丹

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

    2016 年 2 月 28 日更新:

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

    【讨论】:

    • 非常感谢您回复我!你的回答澄清了一些事情。我想我可以订阅事件流客户端直接到应用程序端口,而不是通过端口 80 代理?这样,我的事件流可以关闭..?
    • Phusion Passenger 不会在可公开访问的端口上公开您的 Node.js 应用程序,因此您的客户端无法直接访问它。最好的办法仍然是引入 ping 消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多