2010-12-21 31 views
1

我正在爲node.js websocket聊天服務器編寫以下代碼,並且想知道conn附近的變量生存期問題是什麼。如何找到node.js websocket消息的連接?

// 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的副本對應於他們被調用的新連接,還是有機會彼此混合?

回答

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); 

你爲什麼想讓事情變得複雜? :)

編輯:再次通過您的代碼後,我意識到您正在使用偵聽器來區分用戶註冊和消息。對代碼進行了更改。

1

您不能在JavaScript中使用對象作爲關鍵字,[conn]所做的所有操作都是在conn上調用toString()。幾乎沒有人在那裏覆蓋toString()返回有用的東西。

那麼默認情況下返回toString()是什麼?那麼對象就會返回[object Object]

conn應該有一個id財產,這將給你一個獨特的價值,使用作爲一個關鍵。

+0

啊哈!你建議我在兩個地方添加三個字符? – lowerkey 2010-12-21 12:50:34

相關問題