Node.js广播两次

时间:2016-08-25 09:58:05

标签: javascript node.js

我用node.js给出了我的第一步。我试图实现一个简单的聊天室来获取基础知识,但无法弄清楚为什么在每次广播后,会自动发送第二条(空)消息。这种行为大部分时间都会发生,但并非总是如此。我在Windows中使用Netbeans,使用Putty来模拟客户端连接。

控制台输出:

Server running    
::1:60616 joined    
::1:60617 joined
-----------
Broadcasting: 
hello
-----------
Broadcasting:


-----------
Broadcasting: 
goodbye
-----------
Broadcasting: 


-----------

客户1:

Hi ::1:60616!
    hello
goodbye

客户2:

Hi ::1:60617!
::1:60616 says hello::1:60616 says
::1:60616 says goodbye::1:60616 says

代码

var net = require('net');

var chatServer = net.createServer();
var clientList = [];

console.log('Server running');

chatServer.on('connection', function (client) {

    client.name = client.remoteAddress + ':' + client.remotePort;
    client.write('Hi ' + client.name + '!\n');

    console.log(client.name + ' joined');

    clientList.push(client);

    client.on('data', function (data) {

        console.log('Broadcasting: ');
        console.log(data.toString());
        console.log('-----------');

        broadcast(data, client);
    });

    client.on('end', function () {
        console.log(client.name + ' quit');
        clientList.splice(clientList.indexOf(client), 1);
    });

    client.on('error', function (e) {
        console.log(e);
    });
});

function broadcast(message, sender) {

    var text = sender.name + " says " + message;

    var cleanup = [];

    clientList.forEach(function (client) {

        if (client !== sender) {

            if (client.writable) {                
                client.write(text);
            } else {
                cleanup.push(client);
                client.destroy();
            }
        }
    });

    cleanup.forEach(function (client) {
        clientList.splice(clientList.indexOf(client), 1);
    });
}

chatServer.listen(9000);

1 个答案:

答案 0 :(得分:2)

您无法依靠原始data事件向您展示"全面的"大块的数据。它可能是碎片,你无法控制这些碎片的大小,或者它们在特定的边界上分裂。

但是,有些模块可以帮助您,例如split,它会将数据拆分为单独的(完整)行:

const split = require('split');
...
client.pipe(split()).on('data', function (data) {
  // `data` is now a separate line
  console.log('Broadcasting: ');
  console.log(data.toString());
  console.log('-----------');

  broadcast(data, client);
});