【问题标题】:socket.io: disconnect event isn't firedsocket.io:没有触发断开事件
【发布时间】:2012-05-07 17:23:23
【问题描述】:

我做了一个简单的实时访客计数器。

您可以从this repository下载。

服务器上的断开连接事件(即使在浏览器关闭后)永远不会被触发。

server.js 是:

(function () {
var app, count, express, io;

express = require('express');
io = require('socket.io');

app = module.exports = express.createServer();

app.configure(function () {
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(require('stylus').middleware({
        src: __dirname + '/public'
    }));
    app.use(app.router);
    return app.use(express.static(__dirname + '/public'));
});

app.configure('development', function () {
    return app.use(express.errorHandler({
        dumpExceptions: true,
        showStack: true
    }));
});
app.configure('production', function () {
    return app.use(express.errorHandler());
});

io = require('socket.io').listen(app);

count = 0;

io.sockets.on('connection', function (socket) {
    count++;
    io.sockets.emit('count', {
        number: count
    });
});

io.sockets.on('disconnect', function () {
    console.log('DISCONNESSO!!! ');
    count--;
    io.sockets.emit('count', {
        number: count
    });
});


app.get('/', function (req, res) {
    return res.render('index', {
        title: 'node.js express socket.io counter'
    });
});
if (!module.parent) {
    app.listen(10927);
    console.log("Express server listening on port %d", app.address().port);
}

}).call(this);

客户端上的脚本是:

    script(type='text/javascript')

        var socket = io.connect();

        socket.on('count', function (data) {
            $('#count').html( data.number );
        });

【问题讨论】:

    标签: node.js events socket.io disconnect


    【解决方案1】:

    将您的断开连接代码放在您的连接块中,然后像这样编辑它:

    io.sockets.on('connection', function (socket) {
        count++;
        io.sockets.emit('count', {
            number: count
        });
    
        socket.on('disconnect', function () {
            console.log('DISCONNESSO!!! ');
            count--;
            io.sockets.emit('count', {
                number: count
            });
        });
    });
    

    通过这种方式,您可以检测特定套接字(特别是传递给在连接上运行的匿名函数的套接字)何时断开。

    【讨论】:

    • 你注意到我上面写了socket.on吗?
    • 仅供参考,如果 xhr-polling 用于传输,则在断开连接之前可能会有相当长的延迟。
    • XHR-Polling 是否也会影响连接事件?
    • 正如@NoNameProvided 提到的,断开连接事件应该使用once 而不是on
    【解决方案2】:

    从 Socket.IO 1.0io.engine.clientsCount 属性可用。此属性告诉您您的应用当前有多少打开的连接。

    io.sockets.on('connection', function (socket) {
        io.sockets.emit('count', {
            number: io.engine.clientsCount
        });
    
        socket.once('disconnect', function () {
            io.sockets.emit('count', {
                number: io.engine.clientsCount
            });
        });
    });
    

    注意:使用.once而不是.on,监听器将自动从socket中移除,这对我们现在有好处,因为每个套接字只触发一次disconnect事件。

    【讨论】:

      【解决方案3】:

      以防万一其他人犯了这个愚蠢的错误:确保您定义的任何套接字中间件最后调用next(),否则不会运行其他套接字处理程序。

      // make sure to call next() at the end or...
      io.use(function (socket, next) {
          console.log(socket.id, "connection middleware");
          next(); // don't forget this!
      });
      
      // ...none of the following will run:
      
      io.use(function (socket, next) {
          console.log(socket.id, "second middleware");
          next(); // don't forget this either!
      });
      
      io.on("connection", function (socket) {
          console.log(socket.id, "connection event");
          socket.once("disconnect", function () {
              console.log(socket.id, "disconnected");
          });
      });
      

      【讨论】:

      • 这个 next() 真的花了我几个小时才找到。这是我在套接字断开连接后立即执行操作所需的。应该更明显。
      猜你喜欢
      • 2013-04-03
      • 2011-11-03
      • 2014-01-08
      • 2016-09-20
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 2012-12-19
      相关资源
      最近更新 更多