2012-04-26 28 views
26

He creado un contador de visitantes en tiempo real simple.socket.io: el evento de desconexión no se ha activado

Puede descargarlo desde this repository.

Lo que sucede es que el evento de desconexión (incluso después del cierre del navegador) en el servidor nunca se activa.

server.js es:

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

de secuencias de comandos en el cliente es:

script(type='text/javascript') 

     var socket = io.connect(); 

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

Respuesta

44

Ponga su código de desconexión dentro de su bloque de conexión y editarlo un poco así:

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 esta manera está detectando cuando un socket específico (específicamente el socket que pasa a su función anónima que se ejecuta en la conexión) está desconectado.

+0

¿Notaste que he escrito socket.on arriba? – swiecki

+0

Perfecto, ahora funciona bien –

+5

FYI, si xhr-polling se utiliza para el transporte, puede haber un gran retraso antes de la desconexión. –

2

De Socket.IO 1.0 la propiedad io.engine.clientsCount está disponible. Esta propiedad te dice cuántas conexiones abiertas tiene tu aplicación actualmente.

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

Nota: El uso .once en lugar de .on y el oyente serán eliminados automáticamente de la socket lo que es bueno para nosotros, ya que el evento de desconexión solamente se dispara una vez al zócalo.

0

Por si acaso alguien más cometió este tonto error: asegúrese de que cualquier middleware de socket que haya definido llame al next() al final, o de lo contrario no se ejecutarán otros manejadores de socket.

// 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"); 
    }); 
}); 
Cuestiones relacionadas