2012-04-26 71 views
26

我已經做了一個簡單的實時訪問計數器。socket.io:斷開連接事件沒有被解僱

您可以從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); 
     }); 

回答

44

把你的上斷開代碼的內部連接塊和編輯它有點像這樣:

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

這樣你就可以檢測到一個特定的套接字(特別是你傳遞給你運行的匿名函數的套接字在連接上)被斷開。

+0

您是否注意到我已經寫上了socket.on? – swiecki 2012-04-26 23:06:43

+0

完美,現在工作正常 – 2012-04-26 23:08:27

+5

僅供參考,如果xhr-polling用於運輸,在斷開連接之前可能會有相當長的延遲。 – 2014-01-21 04:30:49

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什麼現在是爲我們好被移除,因爲斷開連接時,只有每個插槽觸發一次。

0

只是爲了防止其他人犯這個愚蠢的錯誤:確保您定義的任何套接字中間件在最後調用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"); 
    }); 
});