Nodejs学习笔记之NET模块(2)


//  Sever --> Client 的单向通讯
var net = require('net');
var chatServer = net.createServer();
chatServer.on('connection', function(client) {
  client.write('Hi!\n'); // 服务端向客户端输出信息,使用 write() 方法
  client.write('Bye!\n');
  client.end(); // 服务端结束该次会话
});
chatServer.listen(9000);

Telnet测试一下:telnet127.0.0.1:9000

执行 telnet后,与服务点连接,反馈 Hi! Bye! 的字符,并立刻结束服务端程序终止连接。

如果我们要服务端接到到客户端的信息?

可以监听 server.data 事件并且不要中止连接(否则会立刻结束无法接受来自客户端的消息)。

(2),监听 server.data 事件并且不要中止连接(否则会立刻结束无法接受来自客户端的消息)。

复制代码 代码如下:


// 在前者的基础上,实现 Client --> Sever 的通讯,如此一来便是双向通讯
var net = require('net');
var chatServer = net.createServer(),   
    clientList = [];
chatServer.on('connection', function(client) {
  // JS 可以为对象自由添加属性。这里我们添加一个 name 的自定义属性,用于表示哪个客户端(客户端的地址+端口为依据)
  client.name = client.remoteAddress + ':' + client.remotePort; 
  client.write('Hi ' + client.name + '!\n'); 
  clientList.push(client); 
  client.on('data', function(data) {   
     broadcast(data, client);// 接受来自客户端的信息 
  });
});
function broadcast(message, client) { 
    for(var i=0;i<clientList.length;i+=1) {   
      if(client !== clientList[i]) {     
        clientList[i].write(client.name + " says " + message);   
      } 
    }
}
chatServer.listen(9000);

上面是不是一个完整功能的代码呢?我们说还有一个问题没有考虑进去:那就是一旦某个客户端退出,却仍保留在 clientList里面,这明显是一个空指针。

(3),处理clientList

复制代码 代码如下:


chatServer.on('connection', function(client) {
  client.name = client.remoteAddress + ':' + client.remotePort
  client.write('Hi ' + client.name + '!\n');
  clientList.push(client)
  client.on('data', function(data) {
    broadcast(data, client)
  })
  client.on('end', function() {
    clientList.splice(clientList.indexOf(client), 1); // 删除数组中的制定元素。
  })
})

NodeTCPAPI已经为我们提供了 end 事件,即客户端中止与服务端连接的时候发生。

(4),优化broadcast

复制代码 代码如下:


function broadcast(message, client) {
  var cleanup = []
  for(var i=0;i<clientList.length;i+=1) {
    if(client !== clientList[i]) {
      if(clientList[i].writable) { // 先检查 sockets 是否可写
        clientList[i].write(client.name + " says " + message)
      } else {
        cleanup.push(clientList[i]) // 如果不可写,收集起来销毁。销毁之前要 Socket.destroy() 用 API 的方法销毁。
        clientList[i].destroy()
      }
    }
  }  //Remove dead Nodes out of write loop to avoid trashing loop index
  for(i=0;i<cleanup.length;i+=1) {
    clientList.splice(clientList.indexOf(cleanup[i]), 1)
  }
}

注意的是一旦 “end” 没有被触发,会出现异常,所以才做优化工作。

(5),NetAPI中还提供一个 error 事件,用于捕捉客户端的异常

复制代码 代码如下:


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

四,总结一下

1,理解开篇的相关概念

2,认识Http与Net模块之间的关系

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgxzxg.html