我如何处理Socket.io中的closures事件?

我正在做基于Web的简单networking游戏。 该游戏使用Socket.io互相连接。 但是我遇到了这个问题。

想想下面的情况。 我跑了Socket.io服务器。 一个玩家进入房间,另一个玩家join房间。 他们玩了一段时间的游戏..但一个玩家很生气,closures游戏标签。

在这种情况下,怎样才能得到一个客户端在服务器端closures浏览器的事件?

按照谷歌search,人们这样说:“使用像onBeforeUnload的浏览器closures事件”

但我知道所有浏览器都不支持onBeforeUnload事件。 所以我想在SERVER SIDE中检查客户端断开事件的解决scheme。

在Socket.io(nodeJS)服务器端控制台中,当客户端的连接closures时,控制台如下所示:

debugging – 丢弃传输

我的nodeJS版本是0.4.10,而Socket.io版本是0.8.7。 并且都在Linux上运行。

任何人都可以帮忙吗?

短代码在这里:

var io = require ( "socket.io" ).listen ( 3335 ); io.sockets.on ( "connection" , function ( socket ) { socket.on ( "req_create_room" , function ( roomId ) { var socketInstance = io .of ( "/" + roomId ) .on ( "connection" , function ( sock ) { sock.on ( "disconnect" , function () { // i want this socket data always displayed... // but first-connected-client doesn't fire this event .. console.log ( sock ); } }); }); }); 

更新:我为这个解决scheme创build了一个博客文章 。 欢迎任何反馈!

我build议对Socket IO使用'卸载时同步断开连接'选项。 我有类似的问题,这真的帮了我。

在客户端:

 var socket = io.connect(<your_url>, { 'sync disconnect on unload': true }); 

无需在任何卸载或事件发生前连线 。 尝试了几个浏览器,并完成迄今为止。

有一个事件disconnectsocket.io连接死亡时触发(请注意,您需socket.io ,因为您可能仍然打开一个wep页面,但是如果您的互联网连接disconnect了)。 尝试这个:

 var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.on('disconnect', function () { io.sockets.emit('user disconnected'); }); }); 

在你的服务器上。 采取从Socket.IO网站 。

//编辑

所以我看了你的代码,并在我的地方做了一些testing。 我得到了和你一样的结果,这里是我的解释。 您试图通过dynamic强制它侦听不同的url(在运行时添加)来使Socket.IO非常dynamic。 但是当第一个连接被build立的时候,服务器不会听到其他的URL。 看起来正是在这一点上(当连接被接受时) disconnect处理程序被设置为第一个连接,并且以后不会更新(请注意,当您在客户端多次调用io.connect时,Socket.IO不会创build新的连接侧)。 总而言之,这似乎是一个错误! 或者也许有一些奇怪的解释,为什么这种行为应该是这样,但我不知道。

让我告诉你一些其他的事情。 首先,听众的这种动力创造似乎不是一个好方法。 在我看来,你应该做以下几点:存储现有的房间,并使用一个url的所有。 保存一个房间的ID,当你发出message事件,例如从客户端添加一个房间的ID到数据,并在服务器处理一个message处理器。 我想你应该已经明白了。 将dynamic部分推入数据,而不是url。 但我可能是错的,至less这是我的意见。

另一件事是你写的代码似乎是不好的。 请注意, .on('connection', handler)运行.on('connection', handler)会使其多次启动。 处理程序堆叠到另一个上,它们不会互相replace。 所以这是我如何实现这个:

 var io = require("socket.io").listen(app); var roomIds = []; function update_listeners(id) { io.of("/"+id).on("connection", function(socket) { console.log("I'm in room " + id); socket.on("disconnect", function(s) { console.log("Disconnected from " + roomId); }); }); } var test = io.sockets.on("connection", function(socket) { console.log("I'm in global connection handler"); socket.on("req_create_room", function(data) { if (roomIds.indexOf(data.roomId) == -1 ) { roomIds.push(data.roomId); update_listeners(data.roomId); } test.emit("room_created", {ok:true}); }); socket.on("disconnect", function(s) { console.log("Disconnected from global handler"); }); }); 

请记住,在侦听器定义之前创build连接的问题仍将出现。