繁体   English   中英

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

[英]node.js simple tcp chat server

我正在尝试构建一个没有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”}这样的消息,您将看到一条消息,提示您尼克加入了您的餐桌。

现在,如果您根据它存储表名的事实向其发送其他内容,则它应该回显您发送给它以及具有相同昵称但在同一张表上的其他连接的任何内容,但是服务器死亡,并抛出错误allSockets对象没有“ for”或“ forEach”方法或indexOf或任何其他方法。

所以,我该如何纠正呢?

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

我试过了hasOwnProperty,但是返回的是布尔值,它仅告诉我存在具有该属性的套接字,但是如何将它们放入for或foreach循环中以便对其进行写入。

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

顺便说一下,我将这些示例与网络示例结合在一起。

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

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

allSockets.sockets.forEach(function(socket) {

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM