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,如何避免记录连接时间或考虑页面刷新/多个套接字?的主要内容,如果未能解决你的问题,请参考以下文章
将 Socket.io 浏览器客户端连接到本地 Node.js 网络服务器
无法从Win Forms C#app连接到远程Node.js Socket.IO服务器