node.js简单的tcp聊天服务器

时间:2012-12-09 14:22:13

标签: node.js tcp network-programming

我正在尝试构建一个简单的tcp聊天服务器,WITHOUT socket.io。 现在,在连接到服务器的所有套接字上广播数据都没有问题。

我的问题是为每个连接分配套接字标识符并从对象中检索它们。

以下是代码:

var net = require('net');

//keep track of sockets
var allSockets = {
  sockets: {},
  addSocket: function(socket, nick, table) {
    this.sockets[table+nick] = socket;
  },
  removeSocket: function(nick, table) {
    if (this.sockets[table+nick] !== undefined) {
      this.sockets[table+nick] = null;
      delete this.sockets[table+nick];
    }
  }
};

// create the server
var server = net.createServer(function (socket) {
  var connected = false;
  var jsoncommand = true;

  //first data sent MUST BE json formatted string in this format 
  //{"nick":"someid","table":"tablenumber"}

  var thisnick = "";
  var thistable = "";

  // get client ip
  socket.name = socket.remoteAddress;

  //write something on each connect
  socket.write("You are connecting from " + socket.name + "\n");
  socket.write(socket.name + " joined chat\n");

  //handle data streams
  socket.on('data', function (data) {
    if (jsoncommand) {
      //JSON.parse the first data stream
      var some = JSON.parse(data);

      //assign a socket.id based on nick and table
      allSockets.addSocket(socket, some.table, some.nick);

      socket.write(some.nick + " joined " + some.table + "\n");
      thisnick = some.nick;
      thistable = some.table;

      connected = true;

      //no longer waiting for first stream as JSON
      jsoncommand = false;
    } else if (connected) {
      //write whatever data it recieves (function is below)
      broadcast(data, thistable);
    } else {
      socket.write("You are not connected to any table");
      socket.destroy();
      connected = false;
      jsoncommand = true;
      thisnick = "";
      thistable = "";
    }
  });

  // remove the socket from allSockets but broadcast 
  //only to other users on the same table
  socket.on('end', function () {
    allSockets.removeSocket(thisnick, thistable);
    broadcast(thisnick + " has left table " + thistable, thistable);
  });

  //this function should select from the allSockets object, 
  //only those, whose property matches "table"
  //and write to those sockets only, when called

  function broadcast(message, table) {
    allSockets.sockets.forEach(function(socket) {
      if (socket.hasOwnProperty(table)) {
        socket.write(message);
      }
    });
  }
});

server.listen(8000);
console.log("running at port 8000\n");

只需将此部署在您的计算机上,然后将nc连接到端口8000即可 并确保你发送的第一件事就是这样的 { “缺口”: “mynick”, “表”: “mytable的”} 你会看到一条消息,说明你的昵称加入了你的桌子。

现在,如果您根据存储表名的事实发送其他内容, 它应该回应你发送给你的任何东西,你和其他不同的联系 nicks但在同一个表上,但服务器死了,抛出了allSockets的错误 object,没有“for”或“forEach”方法或indexOf,或任何其他。

那么,我该如何纠正这个?

如果我的昵称是“john”,我加入了“my_table”,也加入了“mary”,“lisa”和“ana”加入了同样的“my_table”,假设我不知道他们的缺点,但我知道他们在“my_table”, 如何从allSockets对象中选择那些包含“my_table”的套接字。

我尝试过hasOwnProperty,但是返回boolean,它只告诉我有带有该属性的套接字,但是如何将它们放在for或foreach循环中以便写入它们。

我知道这可能是一个愚蠢的问题,或者我甚至不能正确地接受这个问题,但我是一个node.js初学者,所以任何建议都是非常有用的。

顺便说一句,我将这些内容放在网上的例子中。

对于JSON字符串,它是连接桌面应用程序发送的第一件事。无论如何,我选择它进行测试,所以不要理会它。

1 个答案:

答案 0 :(得分:0)

我认为关于forEach的错误发生在这里:

allSockets.sockets.forEach(function(socket) {

虽然allSockets.sockets不是Array,但它是object(键>值模型,类似哈希表)。

因此,要遍历其中的每个套接字,您应该将循环更改为:

for(var key in allSockets.sockets) {
  var socket = allSockets.sockets[key];
  // your logic here
}