我如何找到node.js websocket消息的连接?

时间:2010-12-21 10:07:27

标签: javascript node.js websocket

我正在为node.js websocket聊天服务器编写以下代码,并想知道conn周围的变量生命周期问题是什么。

// chat-server.js
// Joshua Marshall Moore
// 12/20/2010

var ws = require("../../lib/ws/server");
var server = ws.createServer();

conns = [];
server.addListener("connection", function(conn){
    function runHandler(msg){
        server.broadcast(JSON.stringify({"who": conns[conn], "when": Date.now(), "what": msg}));
    }

    function setupHandler(msg){
        if(conns.indexOf(msg)==-1 && msg!="Server"){
            // name has not been taken yet
            conns[conn] = msg;
            conn.send("name ok");

            server.broadcast(JSON.stringify({
                "who": "Server", 
                "when": Date.now(),
                "what": msg + " has joined us"
            }));

            conn.removeListener("message": setupHandler);
            conn.addListener("message": runHandler);
            return;
        }

        conn.send("name taken");
    }

    conn.addListener("message", setupHandler);
});

server.addListener("close", function(conn){
    server.broadcast(JSON.stringify({
        "who": "Server",
        "when": Date.now(),
        "what": conns[conn] + " has left us."
    }));

    delete conns[conn];
});

server.listen(16007);

上面的代码将运行。服务器连接,提交一个名称,直到服务器说它没问题。从客户端发送到服务器的任何消息都会转发给所有客户端。

我试图将连接用作密钥,以便稍后检索客户端提交的名称。 但是,当第二个客户端连接时,所有消息都显示为来自最后一个要连接的人。

我希望这里的某些人能够了解conn变量的整个范围。 从它的外观来看,conn是为服务器连接事件注册的匿名函数的本地。因此,匿名函数内部定义的函数本身可以访问conn。

我更具体的问题是:每次建立新连接时都会调用匿名函数。这是否意味着每次发生时,函数setupHandler和runHandler都使用与它们被调用的新连接相对应的conn副本,或者它们是否有机会相互混合?

2 个答案:

答案 0 :(得分:1)

您不能在JavaScript中使用对象作为键,[conn]所做的只是在toString()上调用conn。几乎没有人覆盖toString()以返回有用的东西。

那么toString()默认返回什么?对于对象,它返回[object Object]

conn应该有一个id属性,它会为您提供一个唯一值来用作密钥。

答案 1 :(得分:1)

@Ivo是关于你不能使用对象作为键的事实。

但是,正如您所指出的那样,问题肯定在于范围。 setupHandler中的conn是最后连接的客户端。你为什么不这样做:

server.addListener("connection", function(conn){
    conn.addListener("message", function(msg){
        if(conn.connected_username !== msg && msg!="Server"){
            if(conn.isRegistered === true) {
              server.broadcast(JSON.stringify({"who": conn.connected_username, "when": Date.now(), "what": msg}));
            } else {
              // name has not been taken yet so assign it!
              conn.connected_username = msg;
              conn.send("name ok");

              server.broadcast(JSON.stringify({
                "who": "Server", 
                "when": Date.now(),
                "what": msg + " has joined us"
              }));

              conn.isRegistered = true;
            }
            return;
        }

        conn.send("name taken");
    });
});

server.addListener("close", function(conn){
    server.broadcast(JSON.stringify({
        "who": "Server",
        "when": Date.now(),
        "what": conn.connected_username + " has left us."
    }));
});

server.listen(16007);

你为什么要把事情弄复杂? :)

编辑:再次查看代码后,我意识到您正在使用侦听器来区分用户注册和消息。对代码进行了更改。