Socket使用的Socket.node.js服务中的IO事件

Socket used by socket.io events in a node.js service

本文关键字:Socket IO 事件 服务 node js      更新时间:2023-09-26

恐怕这很难解释,说实话,我真的不能指望任何人把所有这些都讲完,但我不知道还能怎么解释。

我似乎有一个问题链接用户名套接字在node.js套接字。io服务。我找到了一个相当标准的聊天示例,并根据我的需要对其进行了修改,并拥有

一直在尝试从javascript客户端测试其性能。客户端应用程序有一个用户界面,允许它指定要建立多少连接,然后点击

按钮打开所有连接。当connect事件在客户机中触发时,我发送一个用户名("User"+连接号),并尝试在服务器上处理这个事件。

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

待测性能

我的问题是,在服务器上使用的事件似乎有错误的套接字对象(最后一个客户端已连接)。我可以看出为什么

会出现这种情况

async的原因,但我不知道如何解决它。这是我的小服务器应用程序:

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

套接字。Id显示在前5条连接消息中,看起来很棒!正如我所期望的那样,它们都是不同的。

当客户端登录时,下一个消息的socketID显示每个登录用户的相同(上次连接)socketID。这意味着我不能针对

设置用户名

socket be,因为这样所有用户名都与同一个socket相关联。

客户端浏览器界面如下:

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条消息来自客户端套接字连接事件,并显示服务器的socketID对于这5个连接都是相同的。这意味着登录套接字不在

错误,但客户端的连接为最后一个套接字触发5次,而不是为每个客户端套接字触发一次。然后在

处的那个套接字上进行登录。

客户端,因此在服务器端触发时是错误的。

所以它是可能的服务器代码没有错,问题是我的for循环在客户端?这种类型的for循环在异步世界中是不存在的吗?

任何建议或见解都是非常欢迎的,因为我已经在这上面花了很长时间了。

谢谢

这是您的客户端的问题。重要的两点是,只有函数在javascript中创建新的作用域(特别是,for循环不会),以及闭包在javascript中的工作方式——它们捕获变量,而不是变量的内容。

所以,发生的事情是,你的循环的每次迭代都使用相同的socket变量,但将其设置为不同的套接字,所以当循环结束时,一个socket变量包含最后创建的套接字。然后,一旦套接字的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 }));
}