【问题标题】:Nodejs socket write to all connectionsNodejs套接字写入所有连接
【发布时间】:2018-09-07 13:32:06
【问题描述】:

我在节点中有一个套接字服务器。当它恢复一条新消息时,它会将其写入套接字。但它已从中恢复,写入相应的套接字,而不是所有连接。

服务器.js

var server = net.createServer(function(sock){

    console.log('new client connected');

    sock.on('data', function(data) {
        console.log('Server received');

        // ** NOT sending to all clients **
        sock.write('broadcasting to others...');

    });

}); 

客户端.js

var client = new net.Socket();

client.connect(PORT, HOST, function() {
    console.log('Client connected to: ' + HOST + ':' + PORT);
    // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client 
    client.write('Client is connected!!');

});

client.on('data', function(data) {    
    console.log('Client received: ' + data);
});

如何向所有其他客户端广播一条客户端消息?

【问题讨论】:

    标签: node.js sockets


    【解决方案1】:

    按照我的建议使用Set 来跟踪所有连接的套接字,这是实现它的一种方法。此实现通过监听connect 事件和end 事件来维护Set 作为连接来来去去。

    此实现还支持向所有连接的套接字发送所需的功能,触发事件的套接字除外(我认为这是您的情况所需要的):

    // Set of all currently connected sockets
    const connectedSockets = new Set();
    
    // broadcast to all connected sockets except one
    connectedSockets.broadcast = function(data, except) {
        for (let sock of this) {
            if (sock !== except) {
                sock.write(data);
            }
        }
    }
    
    const server = net.createServer(function(sock){
        console.log('new client connected');
        connectedSockets.add(sock);
    
        sock.on('end', function() {
            connectedSockets.delete(sock);
        });
    
        sock.on('data', function(data) {
            console.log('Server received');
    
            connectedSockets.broadcast(data, sock);
        });
    
    }); 
    

    【讨论】:

    • 谢谢。这正是我所需要的。
    【解决方案2】:

    我相信当每个客户端建立与服务器的连接时,您始终可以将它们的套接字引用保存在一个数组中。要广播,只需循环数组并使用执行write()

    var clients = [];
    var server = net.createServer(function(sock){
    
       console.log('new client connected');
       clients.push(sock);
    
       sock.on('data', function(data) {
            console.log('Server received');
            for(var i = 0; i < clients.length; i++) clients[i].write('broadcasting..');
       });
    
    });
    

    或者,如果您对服务器和客户端都有控制权,我认为最好使用websocketsocket.io,因为它提供广播功能。

    【讨论】:

    • 如果您要跟踪所有当前连接,还必须在断开连接时从 clients 数组中删除项目。
    • @jfriend00 你的意思是我必须在onclose 事件中删除它们?我怎么知道我必须删除哪个索引?
    • @vahidnajafi - 如果它是一个简单的数组,那么您必须搜索数组(可能使用.indexOf() 来寻找匹配的socket 以找到要删除的正确索引。就个人而言,我可能会使用 Set 对象,而不是数组,因为顺序并不重要,而且 Set 使添加、删除和迭代项目变得容易。
    • 如果你想跟踪,使用对象会更好,正如@jfriend00 建议的那样。在存储之前为套接字设置一个属性,例如 socket.name。然后存储将该名称设置为键,将套接字引用设置为值。
    • @Binbo - 我不建议使用普通对象。我建议使用 Set 对象,它允许您直接将套接字添加到 Set - 无需为其命名。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 2014-01-26
    • 1970-01-01
    • 2014-08-25
    • 2016-07-01
    • 1970-01-01
    • 2012-05-18
    • 2015-12-28
    相关资源
    最近更新 更多