2010-12-21 3 views
1

J'écrivais le code suivant pour un serveur de discussion websocket node.js, et je me demandais quels sont les problèmes de durée de vie variable autour de conn.Comment trouver une connexion à un message websocket de node.js?

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

Le code ci-dessus va s'exécuter. Un serveur se connecte, soumet un nom jusqu'à ce que le serveur dise que tout va bien. tout message envoyé du client au serveur est relayé à tous les clients.

J'essayais d'utiliser la connexion comme une clé pour récupérer plus tard le nom soumis par le client plus tôt. Cependant, lorsqu'un second client se connecte, tous les messages sont affichés comme provenant de la dernière personne à se connecter.

J'espérais que quelqu'un ici ait eu un aperçu de la portée de la variable conn tout au long de sa vie. De son apparence, conn est local à la fonction anonyme enregistrée pour l'événement de connexion au serveur. Par conséquent, les fonctions définies à l'intérieur de cette fonction anonyme ont elles-mêmes accès à conn.

Ma question plus spécifique est la suivante: la fonction anonyme est appelée chaque fois qu'une nouvelle connexion est établie. Cela signifie-t-il que chaque fois que cela se produit, les fonctions setupHandler et runHandler utilisent la copie de conn correspondant à la nouvelle connexion qui leur a été demandée, ou y a-t-il une chance qu'elles se mélangent?

Répondre

1

@Ivo a raison sur le fait que vous ne pouvez pas utiliser des objets comme clés. Cependant, comme vous l'avez souligné, le problème est certainement lié à la portée. Le conn dans setupHandler est le dernier client connecté. Pourquoi ne faites-vous pas quelque chose comme ceci:

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

Pourquoi essayez-vous de compliquer les choses? :)

Édition: Après avoir réexaminé votre code, j'ai réalisé que vous utilisez les écouteurs pour faire la distinction entre l'enregistrement de l'utilisateur et le message. Modifications apportées au code

1

Vous ne pouvez pas utiliser des objets comme clés en JavaScript, tout ce que [conn] fait est d'appeler toString() sur conn. Et presque personne ne remplace toString() pour retourner quelque chose d'utile.

Alors qu'est-ce que toString() retourne par défaut? Eh bien pour les objets, il renvoie [object Object].

conn devrait avoir une propriété id, qui vous donnera une valeur unique à utiliser comme une clé.

+0

Aha! Vous suggérez d'ajouter trois caractères à deux endroits chacun? – lowerkey

Questions connexes