web-dev-qa-db-fra.com

socket.io: l'événement de déconnexion n'est pas déclenché

J'ai créé un simple compteur de visiteurs en temps réel.

Vous pouvez le télécharger depuis ce référentiel .

Ce qui se passe, c'est que l'événement de déconnexion (même après la fermeture du navigateur) sur le serveur n'est jamais déclenché.

server.js est:

(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);

Le script sur le client est:

    script(type='text/javascript')

        var socket = io.connect();

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

Mettez votre code de déconnexion dans votre bloc de connexion et modifiez-le un peu comme ceci:

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
        });
    });
});

De cette façon, vous détectez lorsqu'un socket spécifique (en particulier le socket que vous passez à votre fonction anonyme exécutée lors de la connexion) est déconnecté.

50
swiecki

De Socket.IO 1. le io.engine.clientsCount la propriété est disponible. Cette propriété vous indique le nombre de connexions ouvertes de votre application.

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
        });
    });
});

Remarque: utilisez .once au lieu de .on et l'écouteur sera supprimé automatiquement du socket ce qui est bon pour nous maintenant, car l'événement de déconnexion n'est déclenché qu'une seule fois par socket.

3
NoNameProvided

Juste au cas où quelqu'un d'autre aurait fait cette stupide erreur: assurez-vous que tout middleware de socket que vous avez défini appelle next() à la fin, sinon aucun autre gestionnaire de socket ne s'exécutera.

// 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");
    });
});
0
Galen Long