2010-11-28 3 views
2

Ich baue ein Multiuser-Sketchpad und habe Probleme, eine aktualisierte Liste aller aktuell verbundenen Benutzer zu erhalten und zu behalten. Ich versuche, die beste Möglichkeit zu finden, alle vorhandenen Clients eines neuen Clients zu benachrichtigen und die vorhandenen Clients an den neu verbundenen Client zu übergeben. Der Grund, warum ich das versuche, ist so, wenn ein Client eine Zeile zeichnet, alle anderen Clients diesen Client in der Liste finden und die Zeilenkoordinaten dem entsprechenden Array hinzufügen.Abrufen der Liste der Clients mit WebSockets

Server.js

var sys = require("sys"); 
var ws = require('websocket-server'); 

var server = ws.createServer({debug: true}); 

server.addListener("connection", function(conn) { 
// When a message is received, broadcast it too all the clients 
// that are currently connected. 
conn.send('NEW_SERVER_MESSAGE:Welcome!'); 
conn.send('USER_CONNECTED:' + conn.id); 

conn.addListener("message", function(msg){ 
    switch(msg) { 
     case 'GET_ALL_ACTIVE_USERS': 
      server.manager.forEach(function(con) { 
       conn.broadcast('USER_CONNECTED:' + con.id); 
      }); 
      break; 
     case 'UPDATE_CURSOR': 
      conn.broadcast(msg + '_' + conn.id); 
      break; 
     default: 
      conn.broadcast(msg); 
      break; 
    } 

}); 
conn.addListener('close', function(msg) { 
    conn.broadcast('USER_DISCONNECTED:' + conn.id); 
}); 
}); 

server.addListener("error", function(){ 
console.log(Array.prototype.join.call(arguments, ", ")); 
}); 

server.addListener("listening", function(){ 
console.log("Listening for connections..."); 
}); 

server.addListener("disconnected", function(conn){ 
console.log("<"+conn.id+"> disconnected."); 
}); 

server.listen(8002);</code> 

Mein JS Netzcode:

sketchPadNet = function (b,s) { 
var self = this; 

this.host = "ws://localhost:8002/server.js"; 

this.id = null; 
this.users = []; 
this.heightOffset = 53; 
this.scene = s; 
this.connected = b; 

var User = function(id) { 
    this.id = id; 
    this.nickname = id; 
    this.lines = []; 
    this.position = ""; 
}; 

this.init = function() { 
    try { 
     socket = new WebSocket(self.host); 
     socket.onopen = function (msg) { 
      socket.send('GET_ALL_ACTIVE_USERS'); 
     }; 

     socket.onmessage = function (msg) { 
      var m = msg.data.split(':'); 
      switch(m[0]) { 

      case 'USER_CONNECTED': 
       console.log('USER_CONNECTED'); 
       var u = new User(m[1]); 
       u.lines = []; 
       u.nickname = u.id; 
       self.users.push(u); 
       console.log(self.users.length); 
       console.log(self.users); 
       break; 

      case 'USER_DISCONNECTED': 
       console.log('USER_DISCONNECTED'); 
       for(var i = 0; i < self.users.length; ++i) { 
        console.log(self.users[i]); 
        if(m[1] == self.users[i].id) { 
         self.users.splice(i, 1); 
        } 
       } 
       break; 

      case 'DRAW_LINE': 
       var tmpMsg = m[1].split('_'); 

       var id = tmpMsg[8]; 
       var userIndex = ''; 

       for(var i = 0; i < self.users.length; ++i) { 
        if(self.users[i].id == id) userIndex = i; 
       } 

       var p1 = (self.users[userIndex].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[userIndex].lines[self.users[userIndex].lines.length - 1].point2; 
       var p2 = new BLUR.Vertex3(tmpMsg[3], tmpMsg[4], tmpMsg[5]); 

       var line = new BLUR.Line3D(p1, p2, tmpMsg[7]); 
       line.material = tmpMsg[6]; 

       // add the newly created line to the scene. 
       self.scene.addObject(line); 
       self.users[userIndex].lines.push(line); 
       break; 

      case 'UPDATE_CURSOR': 
       for(var i = 0; i < self.scene.objects.length; ++i) { 
        if(self.scene.objects[i].type == 'BLUR.Particle') 
         self.scene.removeObject(scene.objects[i]); 
       } 

       var coords = m[1].split('_'); 
       var id = coords[2]; 
       var userIndex = 0; 

       for(var i = 0; i < self.users.length; ++i) { 
        if(self.users[i].id == id) 
         userIndex = i; 
       } 

       self.users[userIndex].position = new BLUR.Vertex3(coords[0], coords[1], 1); 
       var p = new BLUR.Particle(self.users[userIndex].position, 4); 
       p.material = new BLUR.RGBColour(176,23,31,0.3); 

       self.scene.addObject(p); 
       break; 

      case 'RECEIVE_ID': 
       self.id = m[1]; 
       self.connected.nicknameObj.text = self.id; 
       console.log(self.id); 
       break; 

       break; 
      } 
     }; 

     socket.onclose = function (msg) { 
      // feck! 
      self.connected.addServerError('Server disconnected, try refreshing.'); 
     }; 
    } 
    catch (ex) { 
     console.log('EXCEPTION: ' + ex); 
    } 
}; 

Im Moment, wenn ein neuer Client verbunden sendet er eine Nachricht aus und wird zu einem Array hinzugefügt, die das Gegenteil wenn ein Client die Verbindung trennt. Aus irgendeinem Grund, obwohl dies nicht Update bleibt? Zum Beispiel, wenn ein Client eine Linie zieht, berichten einige der anderen diese Fehler:

Uncaught TypeError: Cannot read property 'lines' of undefined 

Sorry, wenn ich unglaublich hier dumm bin, aber jede Hilfe ist willkommen !!

Prost :)

+0

Sie verwenden also Javascript auf der Serverseite? Welche Art von Rahmen/Container verwenden Sie dafür? –

+0

Ich verwende Node.js mit https://github.com/miksago/node-websocket-server. – harrynorthover

Antwort

2

Ich versuchte es auf den Code, indem Sie, um herauszufinden, aber ohne auch nur eine Zeilennummer, auf dem der Fehler auftritt, dann ist es ziemlich schwer, sowieso.

Ich nehme an, dies ist das Problem hier:

conn.send('USER_CONNECTED:' + conn.id); // send the connect message to ONE user 
conn.broadcast('USER_DISCONNECTED:' + conn.id); // send the disconnect to ALL users 

So scheint es, dass Sie einfach einen Rundruf fehlt, wenn ein Benutzer eine Verbindung.

0

Ok das eigentliche Problem scheint in 'DRAW_LINE' auf der Clientseite zu sein. Sind Sie sicher, dass Sie die Nachricht an alle Benutzer senden und nicht nur die Nachricht an den Client zurücksenden?

Die Fehlerpunkte auf dieser Linie in der Client-Code:

var p1 = (self.users[userIndex].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[userIndex].lines[self.users[userIndex].lines.length - 1].point2; 

Bitte geben Sie den Server-Code für 'DRAW_LINE'. Das Problem taucht definitiv dort auf und nicht in den anderen.

Auch self.users[userIndex] ist undefined. Vielleicht existiert dieser Benutzer nicht?

Warum brauchen Sie diese for-Schleife? Warum nicht einfach:

if(self.users[id] != undefined) { 
    var p1 = (self.users[id].lines.length < 1) ? new BLUR.Vertex3(tmpMsg[0], tmpMsg[1], tmpMsg[2]) : self.users[id].lines[self.users[id].lines.length - 1].point2; 
} 
0

I'm trying to find the best way to notify all existing clients of a new client, and passing the existing clients to the newly connected one

Ich würde Ihnen empfehlen einen Blick auf socket.io statt zu haben. Es kann dies leicht tun und auf andere verfügbare Transporte zurückfallen, wenn Websockets nicht vom Browser unterstützt werden.

0

möchten Sie möglicherweise einen vorhandenen Server verwenden, der Dinge wie Räume und Benutzerlisten eingebaut hat.Zum Vergleich, hier ist eine Anleitung für eine Multi-User-sketchpad in Javascript geschrieben, die Union Server verwendet:

http://www.unionplatform.com/?page_id=2762

und hier ist Union Server dokumentierten Protokoll, das für Räume und Kunden verbinden/leaving Zimmer eine Beschreibung des Nachrichtensystem enthält :

http://unionplatform.com/specs/upc/

könnte Ihnen ein paar Ideen.

colin