【问题标题】:node.js simple tcp chat servernode.js 简单的 tcp 聊天服务器
【发布时间】:2012-11-27 02:47:17
【问题描述】:

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

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

代码如下:

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 并确保您发送的第一件事是 {"nick":"mynick","table":"mytable"} 您将看到一条消息,表明您的昵称已加入您的桌子。

现在,如果您向它发送其他内容,基于它存储了您的表名这一事实, 它应该与您发送的任何内容相呼应,发送给您以及与其他不同的连接 nicks 但在同一张桌子上,但服务器死了,抛出 allSockets 的错误 对象,没有“for”或“forEach”方法或 indexOf 或任何其他方法。

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

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

我尝试了 hasOwnProperty,但它返回布尔值,它只告诉我有具有该属性的套接字,但我如何将它们放入 for 或 foreach 循环中以便写入它们。

我知道这可能是一个愚蠢的问题,或者我什至没有正确解决这个问题,但我是 node.js 初学者,所以任何建议都非常受欢迎。

顺便说一下,我是从网络上的示例中整理出来的。

对于 JSON 字符串,它首先由桌面应用程序在连接时发送。无论如何,我选择它是出于测试目的,所以不要打扰它。

【问题讨论】:

    标签: node.js tcp network-programming


    【解决方案1】:

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

    allSockets.sockets.forEach(function(socket) {
    

    虽然 allSockets.sockets 不是 Array,但它是对象(key > value 模型,如哈希表)。

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

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

    【讨论】:

    • 或使用Object.keys(allSockets.sockets).forEach() :-)
    猜你喜欢
    • 2016-05-06
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多