2010-11-28 64 views
2

我正在构建一个多用户画板并且遇到了一些问题并保留了所有当前连接的用户的更新列表。我试图找到通知所有现有客户端的最佳方式,并将现有客户端传递给新连接的客户端。我试图这样做的原因是,当一个客户端绘制一条线时,所有其他客户端在列表中找到该客户端,并将线条坐标添加到相应的数组中。使用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> 

我的JS网络代码:

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

目前,当一个新的客户端连接它发送一个消息并且被添加到阵列中,所述反向当客户端断开连接时。由于某些原因,虽然这不是保持更新?例如,当一个客户端画线,其他一些人报告这个错误:

Uncaught TypeError: Cannot read property 'lines' of undefined 

很抱歉,如果我被这里令人难以置信的愚蠢,但任何帮助表示赞赏!

干杯:)

+0

因此,您在服务器端使用Javascript?你用什么样的框架/容器? – 2010-11-28 12:12:19

回答

2

我试图通过查看代码,但没有连上出现的错误行号的数字出来,这是相当困难的,反正。

我想这是这里的问题:

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 

如此看来,你只是缺少一个广播呼叫时,用户连接。

0

好的真正的问题似乎在客户端的'DRAW_LINE'。您是否确定要将消息广播给所有用户,而不仅仅是将消息发送回客户端?

错误指向该行客户端代码:

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; 

请为'DRAW_LINE'提供服务器代码。这个问题肯定会在那里出现,而不是其他问题。并且,self.users[userIndex]undefined。也许那个用户不存在?

为什么你需要这个循环?为什么不干脆:

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

我会建议你看看socket.io代替。如果浏览器不支持websockets,它可以轻松完成此操作,并可以恢复到其他可用的传输。

0

您可能会考虑使用现有的服务器,其中包含内置的房间和用户列表等内容。作为比较,下面是用JavaScript编写的多用户画板使用联盟服务器的教程:

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

和这里的联盟服务器的文件协议,其中包括客房和客户的邮件系统的说明,加入/离开房间:

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

可能给你一些想法。

colin