2012-12-09 101 views
0

我想建立一个简单的TCP聊天服务器,无需socket.io。 现在,我没有问题在连接到服务器的所有套接字上广播数据。的Node.js简单的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 并确保您发送的第一件事情是一样的东西 {“尼克”:” mynick“,”table“:”mytable“} 您将看到一条消息,表示您的昵称加入了您的表格。

现在,如果你把它别的东西,根据它存储的表名, 应该呼应无论你把它,你和不同的 缺口等连接,但在同一个表的事实,但服务器死亡,抛出一个错误,allSockets 对象,没有“for”或“forEach”方法或indexOf,或任何其他。

SO,我该如何纠正呢?

如果我的昵称是“john”,并且我加入了“my_table”,并且“mary”,“lisa”和“ana”加入了相同的“my_table”,假设我不知道它们的缺口,但是我确实知道它们在“my_table”上, 如何从allSockets对象中选择包含“my_table”的套接字。

我试过hasOwnProperty,但是它返回的是布尔值,它只告诉我有那个属性的套接字,但是如何将它们放在for或foreach循环中才能写入它们。

我知道这可能是一个愚蠢的问题,也许我不是连正常aproaching这一点,但我是一个node.js的初学者,所以任何意见大大apreaciated。

顺便说一句,我从整个网络的例子放在了一起。

至于JSON字符串,它的第一件事是sentby上连接一个桌面应用程序。无论如何,我选择它用于测试目的,所以不要打扰它。

回答

0

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

allSockets.sockets.forEach(function(socket) { 

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

因此,要通过它的每个插座回路,你应该改变环路:

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

或者使用'Object.keys(allSockets.sockets).forEach()':-) –