socket.io:断开事件不被触发

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

你可以从这个仓库下载它。

会发生什么情况是,服务器上的断开连接事件(即使在浏览器closures后)从未被触发

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

把你的断开连接代码放在你的连接块上,编辑它有点像这样:

 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.IO 1.0中io.engine.clientsCount属性可用。 这个属性告诉你你的应用程序当前有多less打开的连接。

 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删除,这对于我们来说是有好处的,因为断开连接事件每个套接字只能被触发一次。

为了防止其他人犯这个愚蠢的错误:确保你在最后定义了调用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"); }); });