2016-08-25 70 views
0

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

控制台输出:

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); 

回答

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); 
}); 
+0

谢谢,罗伯特。你的回答解决了它。除此之外,我只需要包含'os'模块,并用'os.EOL'替换'\ n'以正确格式化客户端输出中的消息。 –

+0

@ R.Costa oh right,'data'不会(默认情况下)包含行尾。 – robertklep