Socket.io node.js,如何避免记录连接时间或考虑页面刷新/多个套接字?

Posted

技术标签:

【中文标题】Socket.io node.js,如何避免记录连接时间或考虑页面刷新/多个套接字?【英文标题】:Socket.io node.js, how to log connection times avoid or account for page refresh/multiple sockets? 【发布时间】:2015-11-02 14:22:51 【问题描述】:

现在,我完全被 socket.io 搞糊涂了,socket 到底是什么,等等。我需要做的是将通过“id”(作为 URL 参数)标识的两个用户连接到一个room,也定义为一个 URL 参数,如下所示:

http://www.example.com/room1/user1
http://www.example.com/room1/user2

客户端:

var socket = io();

在服务器上:

app.get('/:id/:role', function(request, response) 
        var room = request.params.id;
        var user = request.params.role;
        io.sockets.on('connection', function(socket)
                      socket.join(room);
                      console.log(user+' has connected to '+room)
                      socket.on('disconnect', function()
                                socket.leave(room);
                                console.log(user +' has disconnected from '+room);
                                );
                      );

        response.render('pages/room');
        );

我需要在这里做的是在那个特定的“房间”中记录这 2 个用户的连接时间和断开连接时间。连接和断开控制台语句有效,但它们最终会被记录多次,并且在页面刷新时它们开始被记录很多次:

11:20:23 web.1  | user1 has connected to room1 at 1439220023347 //user1 connects
11:20:41 web.1  | user1 has disconnected from room1 at 1439220041842 //user 1 navigates away from page
11:20:44 web.1  | user1 has connected to room1 at 1439220044447 //user 1 returns back to page via back button
11:21:01 web.1  | user1 has connected to room1 at 1439220061168 //user 2 connects to room creates 2 new connection log events?
11:21:01 web.1  | user2 has connected to room1 at 1439220061168

11:23:04 web.1  | user1 has disconnected from room1 at 1439220184527 //user 1 hits 'refresh' all hell breaks loose
11:23:04 web.1  | user1 has connected to room1 at 1439220184727
11:23:04 web.1  | user2 has connected to room1 at 1439220184727
11:23:04 web.1  | user1 has connected to room1 at 1439220184727

如何才能使每个用户只触发一次断开/连接事件,以便我可以在服务器端可靠地记录事件? (最终保存到数据库,但为了便于阅读而省略了)。

【问题讨论】:

这当然是因为您正在为connection 事件创建多个事件侦听器,然后让所有未来的连接加入房间。此设置不起作用,您需要完全更改它。我将从不为此使用快速路由开始,而是使用 socket.io 发出和事件来处理它。 这看起来不像纯节点...你有表达过它还是什么?无论如何,从每次访问页面时的外观来看,您都创建了一个侦听器。所以基本上第一次访问时,你添加一个监听器,所以它记录一次。第二次添加另一个,所以它记录了两次。等等,你需要把监听代码放在 app.get 部分之外。 @zozo 对不起,是的,使用快递。好的,看看我如何通过发射和事件来做到这一点 【参考方案1】:

io.sockets.on('connection', function(socket)... 行是您的套接字的主要事件处理程序,它只需要触发一次,否则您将在每次调用路由时重新创建一个处理程序。通常它看起来像这样:

app.get('/', function (req, res) 
  res.sendfile(__dirname + '/index.html');
);

io.on('connection', function (socket) 
  socket.emit('news',  hello: 'world' );
  socket.on('my other event', function (data) 
    console.log(data);
  );
);

如您所见,路由处理完全独立于套接字事件处理。

现在,您想使用 URL 参数加入房间。因为套接字连接是客户端建立的,它发生在路由被 express 调用之后,因此,客户端可以将这些参数发送到套接字。 (未经测试)简单的例子。

客户:

var socket = io.connect('http://localhost:5000'); //adjust to the port your server is listening on
socket.on('auth',function()
   socket.emit('userParameters',room:room,user:user);
);

服务器:

app.get('/:id/:role', function(request, response) 
   response.render('pages/room');
);

io.on('connection', function(socket)
    socket.emit('auth'); //will be emitted only once to each socket.
    socket.on('userParameters',function(params)
         socket.join(params.room);
         socket.user = params.user;
         console.log(socket.user+' has connected to '+params.room)
    );
    socket.on('disconnect', function()
          console.log(socket.user+' has disconnected'); //disconnecting automatically removes the socket from the room.
    );
);

我强烈建议您阅读documentation,尤其是 Express 示例。

另外,请考虑您将在线阅读的许多文档都是关于 Socket.IORead here to avoid confusion

【讨论】:

我不知道,有人做过……我还没试过。感谢您的回答,我会让您知道我是如何处理的。 我花了点功夫,但这似乎正是我需要的,非常感谢,让我省了很多麻烦。

以上是关于Socket.io node.js,如何避免记录连接时间或考虑页面刷新/多个套接字?的主要内容,如果未能解决你的问题,请参考以下文章

node.js、socket.io 和 SSL

将 Socket.io 浏览器客户端连接到本地 Node.js 网络服务器

无法从Win Forms C#app连接到远程Node.js Socket.IO服务器

尝试将客户端连接到服务器时出现Node.js Socket.io错误

facebook 和 socket.io node.js

使用 node.js、websockets 和 socket.io 创建实时聊天