我如何在Socket.io中处理Close事件?

时间:2012-01-31 10:11:06

标签: node.js socket.io

我正在制作基于Web的简单在线游戏。 游戏使用Socket.io互相进行网络互动。 但是我遇到了这个问题。

考虑以下情况。 我运行了Socket.io服务器。 一个玩家制作房间,其他玩家加入房间。 他们玩游戏一段时间.. 但是一个玩家如此生气并关闭游戏标签。

在这种情况下,如何在服务器端获取一个客户端关闭浏览器的事件?

根据谷歌搜索,人们这样说:“像onBeforeUnload一样使用浏览器关闭事件”

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

在Socket.io(nodeJS)服务器端控制台中,当客户端的连接关闭时,控制台会说如下:

调试 - 丢弃传输

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

2 个答案:

答案 0 :(得分:18)

更新:我为此解决方案创建了a blog post。欢迎任何反馈!

我建议在卸载时使用'同步断开连接'套接字IO的选项。我遇到了类似的问题,这真的帮助了我。

在客户端:

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

无需连接任何卸载 beforeunload 事件。在几个浏览器中尝试过这一点,到目前为止它的工作非常完美。

答案 1 :(得分:7)

有一个事件disconnect会在socket.io连接中断时触发(请注意您需要这个,因为您可能仍然打开了一个wep页面,但是如果您的互联网连接中断了怎么办?)。试试这个:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('disconnect', function () {
    io.sockets.emit('user disconnected');
  });
});

在你的服务器上。取自Socket.IO website

<强> //修改

所以我看了你的代码并在我的地方做了一些测试。我得到了和你一样的结果,这是我的解释。您试图通过动态强制Socket.IO监听不同的URL(在运行时添加)来使Socket.IO非常动态。但是当第一次连接时,服务器在那时不会监听另一个URL。似乎恰好在那一点(当接受连接时)disconnect处理程序被设置为第一个连接并且稍后不会更新(请注意,当您调用{{1}时,Socket.IO不会创建新连接很多次在客户端)。总而言之,这似乎是一个错误!或者也许有一些奇特的解释为什么这种行为应该是这样,但我不知道。

让我告诉你一些其他的事情。首先,这种动态创造听众似乎并不是一个好方法。在我看来,你应该做以下事情:存储现有的房间,并为所有房间使用一个网址。保留房间的ID,当您从客户端发出例如io.connect事件时,将房间的ID添加到数据中,并使用服务器上的一个message处理程序处理此事件。我想你应该已经明白了。将动态部分推入数据,而不是网址。但我可能错了,至少我认为是这样。

另一件事是你写的代码似乎很糟糕。请注意,多次运行message会使其多次触发。处理程序将一个堆叠到另一个上,它们不会互相替换。所以我就是这样实现的:

.on('connection', handler)

请记住,在定义侦听器之前创建连接的问题仍然会发生。