我担心这很难解释,说实话,我真的希望任何人都能完成这一切,但我不知道如何解释它。
我似乎在将一个用户名链接到node.js socket.io服务中的套接字时出现问题。我拿了一个相当标准的聊天样本,我发现并修改了它以满足我的需求并且
一直试图从javascript客户端测试其性能。客户端应用程序具有用户界面,允许它指定要建立的连接数,然后点击
按下按钮打开所有连接。当连接事件在客户端触发时,我发送用户名("用户" +连接号)并尝试在服务器上处理此事件。
在客户端,我正在使用"强制新连接"我连接时的选项,以便使用新连接而不是重新使用以前的连接。我这样做是为了允许
要测试的性能。
我遇到的问题是服务器上使用的事件似乎有错误的套接字对象(最后一个连接的客户端)。我可以理解为什么会发生这种情况
异步原因,但我无法解决它。这是我的小型服务器应用程序:
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);
});
}
},
我将大量数据写入服务器控制台并将一些数据返回给客户端,以便它显示在客户端浏览器中。如果客户端建立了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看起来很棒!正如我所期待的那样,它们各不相同。
客户端登录时下一条消息的socketID为登录的每个用户显示相同的(最后一个连接)套接字ID。这意味着我无法针对
设置用户名套接字导致用户名全部与同一套接字相关联。
客户端浏览器屏幕如下:
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条消息来自客户端套接字连接事件,并显示服务器套接字ID对于5个连接都是相同的。这意味着登录套接字不在
错误但是客户端的连接为最后一个套接字触发了5次而不是每个客户端套接字触发一次。然后登录在
的那个套接字上进行客户端因此在服务器上发生错误时会出错。
那么服务器代码是否可能没有错,问题是我在客户端的for循环?在异步世界中,这种类型的for循环是否为no?
任何建议或见解都非常受欢迎,因为我现在花了很长时间。
由于
答案 0 :(得分:1)
这是您客户的问题。两个要点是只有函数在javascript中创建新的作用域(具体来说,for
循环没有),以及javascript中闭包的工作方式 - 它们捕获变量,而不是变量的内容。
所以,正在发生的事情是你的循环的每次迭代使用相同的socket
变量但是将它设置为不同的套接字,所以当循环结束时,一个socket
变量包含最后一个套接字创建。然后,一旦套接字&#39; connected
事件触发,它们都发出相同的socket
(最后一个)。
您希望创建一个IIFE,通过创建新范围,为每次循环运行分别捕获socket
变量:
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 }));
}