使用socket.io创建已连接客户端列表

8

以下是两个相关问题,同时发布更有意义。

问题1

我有一个node.js应用程序,它向所有客户端发出事件,所有当前客户端都会响应ready。如何创建所有回复初始发射的客户端列表,以及可以用什么样的标识来区分客户端?

问题2:

在收集连接的客户端列表之后,我想做的是访问一个包含N行数据的MySQL数据库表,并为每个客户端分配X行数据。这些行将被发送回各自的客户端。如何实现?

问题1的当前代码

Node代码

setInterval(function() {
    util.log('Checking for new jobs...');
    dbCheckQueue(function(results) {  // checks if there are new rows to "distribute" to clients
        if (results.length) {
            util.log(results.length + ' new jobs found.');
            io.sockets.emit('job_available');
        }
    });
}, 10*1000);

客户端JS代码
socket.on('job_available', function() {
                console.log('Job Available.. Responding with Ready!');
                socket.emit('ready');
            });

io.sockets.on('connection', function(socket) {
    socket.on('ready', function() {
        // UPDATE N rows with client_id in column checkout.
        // Then SELECTS * from table where checkout = client_id
        getListings(client_id, function(listings) {
            socket.emit('job', listings);   // send jobs
        });
    });
});

第二个问题的当前代码 该代码适用于单个客户端,但如何循环遍历所有连接的客户端并执行相同的列更新和行选择操作?

io.sockets.on('connection', function(socket) {
    socket.on('ready', function() {
        // UPDATE N rows with client_id in column checkout.
        // Then SELECTS * from table where checkout = client_id
        getListings(client_id, function(listings) {
            socket.emit('job', listings);   // send jobs
        });
    });
});
2个回答

20

Socket.io为此提供了公共API,因此您不必像Bryan建议的那样进行一些探究,可以使用以下方法:

io.sockets.clients()

这将返回所有已连接客户端的数组。

如果您想获取连接到特定命名空间的所有客户端:

io.of('/namespace').clients()

但是你甚至可以更加过滤它... 如果你想要获得一个房间中的所有套接字:

io.sockets.clients('room name here as first argument')

将返回连接到房间在此作为第一个参数的房间名称的套接字数组。


感谢3rdEden,我使用了Bryan的解决方案,并进行了轻微修改,因为我只想将那些回复“ready”消息的已连接客户端推入数组中。API能否以不同的方式实现此功能? - Nyxynyx
这就是正确的方法!谢谢 :) - Arnaldo Capo
@3rdEden,您是node-memcached的作者吗?我正在很好地使用它 :) - CoderSpinoza
11
我相信这个答案中的功能已经在1.0版本中被废弃了。 - austinheiman
@web-student-ksu,v1.0+版本中针对这种用例的当前解决方案是什么? - newguy
显示剩余2条评论

16

你需要自己跟踪已连接的客户端。最简单的方法是使用数组:

var clients = [];

io.sockets.on('connect', function(client) {
    clients.push(client); 

    client.on('disconnect', function() {
        clients.splice(clients.indexOf(client), 1);
    });
});

然后你可以在服务器上引用 clients 数组,无论何时需要,在你的 ready 事件处理程序或其他地方。类似于:

io.sockets.on('connection', function(socket) {
    socket.on('ready', function() {
        // UPDATE N rows with client_id in column checkout.
        // Then SELECTS * from table where checkout = client_id
        clients.forEach(function(client, index) {
            var client_id = index; // Just use the index in the clients array for now
            getListings(client_id, function(listings) {
                socket.emit('job', listings);   // send jobs
            });
        });
    });
});

你能提供一下 getListings() 函数的逻辑吗?因为我正在应用类似的解决方案,但是在屏幕上只显示了第一个已登录用户的名称。 - johannesMatevosyan
getListings 调用只是我从原始问题中提取的示例代码。我不知道它包含什么或者它是如何实现的。 - rossipedia
我明白了,因为我正在使用数组存储客户端信息,当我尝试通过foreachfor循环检索它们时,我只能在浏览器中看到第一个已登录客户端的用户名。 - johannesMatevosyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接