我正在尝试构建一个简单的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字符串,它是连接桌面应用程序发送的第一件事。无论如何,我选择它进行测试,所以不要理会它。
答案 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
}