0

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、またはその他のメソッドがありません。

SO、どうすればこれを修正できますか?

私のニックネームが「john」で「my_table」に参加し、「mary」、「lisa」、「ana」も同じ「my_table」に参加している場合、彼らのニックネームはわからないと仮定しますが、彼らが参加していることは知っています「my_table」、「my_table」を含むソケットを allSockets オブジェクトから選択するにはどうすればよいですか。

私は hasOwnProperty を試しましたが、それはブール値を返します。これは、そのプロパティを持つソケットがあることだけを教えてくれますが、それらに書き込むために for または foreach ループに入れるにはどうすればよいですか。

ばかげた質問かもしれませんし、これに正しくアプローチしていないかもしれませんが、node.jsの初心者なので、アドバイスは大歓迎です。

ところで、私はこれをウェブ全体の例からまとめました。

JSON 文字列に関しては、接続時にデスクトップ アプリによって最初に送信されます。とにかく、テスト目的で選択したので、気にしないでください。

4

1 に答える 1

0

ここで forEach に関するエラーが発生すると思います:

allSockets.sockets.forEach(function(socket) {

allSockets.sockets は配列ではありませんが、オブジェクトです (ハッシュ テーブルのようなキー > 値モデル)。

したがって、その中の各ソケットをループするには、ループを次のように変更する必要があります。

for(var key in allSockets.sockets) {
  var socket = allSockets.sockets[key];
  // your logic here
}
于 2012-12-20T14:50:10.427 に答える