【问题标题】:Watch for connection termination on incoming HTTP requests - Node.JS观察传入 HTTP 请求的连接终止 - Node.JS
【发布时间】:2011-07-13 10:20:29
【问题描述】:

在 Node.JS 中向另一个 HTTP 服务器发出请求时,您可以监听服务器何时关闭与 request.on('close', function(){}); 的连接。我一直在 Node 的 http.createServer() 中寻找类似的功能。我假设传入回调的请求变量有一个on() 函数,当客户端关闭连接时我可以调用它来监听。

var http = require('http');
http.createServer(function(req, res) {
    req.on('close', function() { console.log("Connection closed"); });
}).listen(80, '127.0.0.1');

但是,在阅读了0.4.9 docs on streams之后,我注意到在关闭事件下它说:

并不是所有的流都会发出这个。 (例如,传入的 HTTP 请求不会发出“关闭”。)

有没有办法在 Node 中监听来自服务器的客户端连接终止?

【问题讨论】:

    标签: javascript http node.js


    【解决方案1】:

    好吧,您可以通过以下方式直接访问套接字:

    req.socket.on('close', ...);
    

    但是,在请求侦听器中执行此操作将为每个请求绑定事件。因此,您应该绑定到连接事件:

    var server = http.createServer();
    server.on('request', function(req, res) { ... });
    server.on('connection', function(socket) {
      socket.on('close', function() {
        console.log(socket.remoteAddress + '\'s keep-alive session died!');
      });
    });
    

    编辑: 也许我应该提到,是的,技术上 http 服务器的套接字对象将携带对 _httpMessage 属性上的响应的引用。但是,我建议不要使用它,因为它是内部 API 的一部分,并且可能会在没有任何警告的情况下进行更改。

    最好添加您自己的属性以获取对上次请求的引用:

    server.on('request', function(req, res) {
      req.socket.currentRequest = req;
    });
    server.on('connection', function(socket) {
      socket.on('close', function() {
        var req = socket.currentRequest;
        console.log('Socket closed. Last request for: ' + req.url);
      });
    });
    

    【讨论】:

    • 如果我要直接绑定到套接字或从请求中绑定到它,我假设套接字不会携带任何标识,可以让我识别它与哪个请求相关联,对吗?我正在尝试在这里编写一个伪媒体服务器,所以我需要知道客户端何时关闭连接,这样我就不会浪费时间,也不会浪费缓冲内存来写入关闭的套接字。但是,我不确定如果连接关闭,请求的回调是否会持续存在。你知道关闭一个请求是否会停止该请求的回调?
    【解决方案2】:

    Socket.io

    当您想知道套接字是否已关闭时,这仅在您执行挂起请求(实时)时才有意义,我建议您改用 socket.io,它会处理所有这些:

    var io = require('socket.io').listen(80);
    
    io.sockets.on('connection', function (socket) {
      io.sockets.emit('this', { will: 'be received by everyone');
    
      socket.on('private message', function (from, msg) {
        console.log('I received a private message by ', from, ' saying ', msg);
      });
    
      socket.on('disconnect', function () {
        sockets.emit('user disconnected');
      });
    });
    

    socket.io 的好处在于它是support by every browser(major),您不必担心小细节(这会让您发疯)。他们用一个很好的 API 将其抽象出来。

    Express:

    或者在使用 Express 时

    var app = require('express').createServer();
    
    app.get('/', function(req, res){
        req.on('close', function () {
            console.log('closed');
        });
    });
    
    app.listen(3000, '127.0.0.1');
    

    【讨论】:

    • Socket.IO 确实消除了实时浏览器到服务器通信两端的头痛,但在此应用程序中将无法工作,因为我试图将媒体文件提供给浏览器以获取 HTML5 视频标签。尽管如此,如果没有这个上下文,Socket.IO 将是 node 内置 http 功能的一个很好的替代品。
    • 我不知道。您是否搜索过开源替代品来做到这一点?
    • 好收获。我会在 github 上查看 express,看看他们是如何做到的。
    猜你喜欢
    • 2016-12-31
    • 2014-06-11
    • 2012-08-27
    • 1970-01-01
    • 2014-04-05
    • 2019-12-20
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多