由node.js服务中的socket.io事件使用的套接字

我恐怕这很难解释,说实话,我真的不能期望任何人经历这一切,但我不知道如何解释它。

我似乎有问题链接到一个node.js socket.io服务的用户名到套接字。 我采取了一个相当标准的聊天样本,我发现并修改了我的需求和拥有

一直试图从一个JavaScript客户端testing其性能。 客户端应用程序有一个用户界面,允许它指定要build立多less个连接,然后点击一个

button打开所有的连接。 当connect事件在客户端触发时,我发送一个用户名(“用户”+连接号),并尝试在服务器上处理这个事件。

在客户端中,当我连接时使用“强制新连接”选项,以便使用新的连接而不是重新使用以前的连接。 我这样做是允许的

性能待测。

我遇到的问题是在服务器上使用的事件似乎有错误的套接字对象(最后一个连接的客户端)。 我可以看到为什么会发生这种情况

asynchronous的原因,但我无法解决它。 这是我的小型服务器应用程序:

var httpd = require('http').createServer(); var io = require('socket.io').listen(httpd); io.sockets.on('connection', function (socket) { noOfConnections = noOfConnections + 1; console.log('SocketID ' + socket.id + ' connected. Connections = ' + noOfConnections); socket.on('login', function(UserName) { socket.set('UserName', UserName, function(err) { if (err) { throw err; } io.sockets.socket(socket.id).emit('serverMessage', 'SocketID (' + socket.id + ') Currently logged in as ' + UserName); console.log('SocketID (' + socket.id + ') ' + UserName + ' logged in. Connections = ' + noOfConnections); }) }); }); httpd.listen(3000); console.log("Server listening on port 3000"); var noOfConnections = 0; 

客户端应用程序的相关部分如下:

  for (var index = 0; index < noOfConnections; index++) { var socket = io.connect('http://192.168.0.12:3000', { 'force new connection': true }); socket.on('connect', function () { userNo = userNo + 1; addMessage("Socket connected Server SocketId = " + socket.socket.sessionid); var username = userNamePrefix + userNo socket.emit('login', username); }); } }, 

我写了大量的数据到服务器控制台,并返回一些数据到客户端,所以它出现在客户端浏览器。 如果客户端build立5个连接,我在服务器上看到这个

安慰:

 Server listening on port 3000 SocketID i0M_578QQZcT0q9yraV_ connected. Connections = 1 SocketID 0c1l31sGy8sl1DkPraWA connected. Connections = 2 SocketID BEmhxokbfd95K-lGraWB connected. Connections = 3 SocketID i0UD5Prnkcu_o29araWC connected. Connections = 4 SocketID mbOSMts7JLCYlT6eraWD connected. Connections = 5 SocketID (mbOSMts7JLCYlT6eraWD) User1 logged in. Connections = 5 SocketID (mbOSMts7JLCYlT6eraWD) User2 logged in. Connections = 5 SocketID (mbOSMts7JLCYlT6eraWD) User3 logged in. Connections = 5 SocketID (mbOSMts7JLCYlT6eraWD) User4 logged in. Connections = 5 SocketID (mbOSMts7JLCYlT6eraWD) User5 logged in. Connections = 5 

前5个连接消息中显示的socket.id看起来很棒! 他们和我所期望的完全不同。

当客户端login时,下一个消息的socketID显示每个login用户的相同(最后一个连接)socketID。这意味着我不能设置用户名

套接字被导致用户名然后都与相同的套接字相关联。

客户端浏览器屏幕如下:

 Socket connected Server SocketId = mbOSMts7JLCYlT6eraWD Socket connected Server SocketId = mbOSMts7JLCYlT6eraWD Socket connected Server SocketId = mbOSMts7JLCYlT6eraWD Socket connected Server SocketId = mbOSMts7JLCYlT6eraWD Socket connected Server SocketId = mbOSMts7JLCYlT6eraWD SocketID (mbOSMts7JLCYlT6eraWD) Currently logged in as User1 SocketID (mbOSMts7JLCYlT6eraWD) Currently logged in as User2 SocketID (mbOSMts7JLCYlT6eraWD) Currently logged in as User3 SocketID (mbOSMts7JLCYlT6eraWD) Currently logged in as User4 SocketID (mbOSMts7JLCYlT6eraWD) Currently logged in as User5 

前5条消息来自客户端套接字连接的事件,并显示服务器套接字标识符全部对于5个连接是相同的。 这意味着login套接字不在

但客户端的连接会为最后一个套接字触发5次,而不是每个客户机套接字触发一次。 login然后发生在那个一个sockets上

客户端,因此在服务器启动时出现错误。

那么有可能服务器代码没有问题,问题是我在客户端的循环? 这种for循环types是不是,在asynchronous世界没有?

任何build议或见解都非常受欢迎,因为我现在花了很长时间。

谢谢

这是您客户的问题。 两个重点是只有函数在javascript中创build新的范围(特别是for循环不),以及javascript中的闭包方式 – 它们捕获variables,而不是variables的内容。

所以,发生什么事情是你的循环的每个迭代使用相同的socketvariables,但将其设置为不同的套接字,所以当循环结束时,一个socketvariables包含最后创build的套接字。 然后,一旦套接字的connected事件触发,它们全都在同一个socket (最后一个socket )上发射。

您将需要创build一个IIFE来通过创build新的作用域来为每个循环运行分别捕获该variables:

 for (var index = 0; index < noOfConnections; index++) { (function(socket) { socket.on('connect', function () { userNo = userNo + 1; if (showDataMessages) { addMessage("Socket connected Server SocketId = " + socket.socket.sessionid); } var username = userNamePrefix + userNo socket.emit('login', username); }); })(io.connect('http://192.168.0.12:3000', { 'force new connection': true })); }