如何检查node.js服务器中的连接是否中止

时间:2011-09-08 13:21:47

标签: node.js connection request abort

我正在使用node.js进行一些长轮询 基本上,node.js服务器接受来自用户的请求,然后检查一些更新。如果没有更新,它将在超时后检查它们 但是如果用户关闭了他的标签,或者去了另一个页面呢?就我而言,脚本继续工作 在用户中止了他的请求(关闭连接)时,node.js中有没有办法检查或检测或捕获事件?

5 个答案:

答案 0 :(得分:22)

您需要使用req.on('close', function(err) { ... });代替req.connection.on('close', function(err) { ... });

有一个非常重要的区别。 req.on()在req.connection.on()中为此请求添加一个侦听器,在客户端和服务器之间的(keep-alive)连接中添加一个侦听器。如果使用req.connection.on(),则每次客户端重新使用连接时,都会向同一连接添加一个侦听器。当连接最终中止时,所有侦听器都会被触发。

函数范围通常可以使您免受此操作系统逻辑的影响,但这仍然是一件危险的事情。幸运的是,至少NodeJS 0.10.26足够聪明,可以警告用户:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace: 
  at Socket.EventEmitter.addListener (events.js:160:15)
  at Socket.Readable.on (_stream_readable.js:689:33)
  ...

答案 1 :(得分:18)

感谢 Miroshko的 yojimbo87的答案,我能够捕捉到“关闭”事件,但我不得不做一些额外的调整。

仅仅抓住'close'事件并没有解决我的问题的原因是当客户端将请求发送到node.js服务器时,如果连接仍然打开,服务器本身无法获取信息,直到他将某些内容发送回客户端(据我所知 - 这是因为HTTP协议) 因此,额外的调整是不时地在回应中写点东西 阻止它工作的另一件事是我将'Content-type'作为'application / json'。将其更改为“text / javascript”有助于不时地关闭“空白”而不关闭连接。
最后,我有这样的事情:

var server = http.createServer(function(req,res){    
    res.writeHead(200, {'Content-type': 'text/javascript'});

    req.connection.on('close',function(){    
       // code to handle connection abort
    });

    /**
     * Here goes some long polling handler
     * that performs res.write(' '); from time to time
     */

    // some another code...
});
server.listen(NODE_PORT, NODE_LISTEN_HOST);

我的原始代码要大得多,所以我不得不削减它以显示敏感部分。

我想知道是否有更好的解决方案,但目前这对我有用。

答案 2 :(得分:4)

  

node.js中是否有办法检查或检测或捕获事件   用户已中止其请求(关闭连接)?

您可以尝试使用http.ServerRequest close event。简单的例子:

var http = require("http"),
    util = require("util");

var httpServer = http.createServer(function(req, res) {
    util.log("new request...");

    // notify me when client connection is lost
    req.on("close", function(err) {
        util.log("request closed...");
    });

    // wait with response for 15 seconds
    setTimeout(function() {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.write("response");
        res.end();

        util.log("response sent...");
    }, 15000);
});
httpServer.listen(8080);
util.log("Running on 8080");

答案 3 :(得分:3)

似乎您的问题与此问题非常相似:

NodeJS HTTP request connection's close event fired twice

request.connection.on('close', function () {
  ... 
}); 

答案 4 :(得分:3)

我正在使用Express.js(~4.10.6),以下代码对我来说很好用:

//GET Request:
app.get('/', function(req, res){
    req.on('close', function(){
        console.log('Client closed the connection');
    });
});

只要我关闭浏览器的标签页,浏览器就会关闭连接,并且回调函数会按预期执行。