Socket.io 多连接

Posted

技术标签:

【中文标题】Socket.io 多连接【英文标题】:Socket.io multiple connections 【发布时间】:2016-09-15 17:26:42 【问题描述】:

我还没有真正找到有关文档的奇怪问题。我认为这可能最终会成为“您不了解产品的工作原理”的简单案例,我希望有人可以填补空白。

这是怎么回事...我有 3 个独立的应用程序,它们是 socket.io 服务器。他们都在监听不同的端口。每个服务器都用于不同的专门用途。我正在构建应用程序,以便我可以部分扩展它,并且只影响我需要更改/更新的各个独立部分。

这很好,直到我意识到对于每个运行的应用程序都有一个额外的套接字连接每个服务器。因此,如果我有 3 个应用程序,那么我在每台服务器上都有 3 个连接。

这方面的证据是,如果我向每个服务器添加一个 console.log("Connected") 然后连接一个客户端,每个服务器报告的连接数与服务器数一样多。希望这是有道理的。

我的目标是每台服务器有 1 个连接。似乎每个连接都充当到所有套接字服务器的通用连接。我的服务器监听器是这样设置的:

io = require('socket.io').listen(26265) // can use up to 26485

我的客户是这样连接的:

socket = new io('http://localhost:26265')

编辑:

添加到我原来的问题,以便您可以看到更多代码...

完整的客户端代码:

importJS('/js/pages/admin_base.js',function()     
        AdminIO = new io('http://localhost:26266');
        AdminIO.on('send_users',function(rows)
            toggleLoad();
            /*
            if(typeof rows === 'object')
                rows = Array(rows);
               
            */  
            appendUsers(rows);       
            console.log(rows);
        );
        AdminIO.on('failed_users',function()
            toggleLoad();
            dropInfo("Failed to retrieve userlist",level: "error");
        );
        AdminIO.on('test',function (q) 
            console.log(q);
        );
    queryUsers(AdminIO);
);

服务器代码很长...所以相关部分是:

var io = require('socket.io').listen(26266); // can use up to 26484
//.... imported additional modules and defined simple functions here
io.on('connection', function (socket)   
    socket.on('restart_request', function(req)
        var success = false
            , session = JSON.parse(req.session)
            , sessionID = session.sessionID;
        checkSession(sessionID, function (ses) 
            if (ses === false)  console.error('CheckSession failed: No session exists'); return; 
            if (ses.user.uuid !== session.uuid)  console.error('CheckSession failed: UUID mismatched'); return; 
            if (ses.user.role < conf['Permissions']['lm_restart']) socket.emit('restart_fail','Insufficient permissions.'); return; 
            if(process.platform === 'win32')            
                executeCMD('START "" .\\windows\\scripts\\restart_lm.bat',function(err,res)
                    var errSent = false;
                    if(err)                        
                        console.error(err);
                        if(!errSent) socket.emit('restart_fail','Restart failed'); 
                        errSent = true;
                        if(res === null)return;
                    
                    console.log(res);
                    socket.emit('restart_success','LM successfully restarted.');
                );                
            
            else if(process.platform === 'linux')

            
        );
    );
    socket.on('get_users',function(req)
          var success = false
            , session = JSON.parse(req.session)
            , opts = req.opts || null
            , sessionID = session.sessionID
            , col = opts.col || null
            , where = opts.where || null
            , range = opts.range || null
            ;
        checkSession(sessionID, function (ses) 
            if (!ses)  console.error('CheckSession failed: No session exists'); return; 
            if (ses.user.uuid !== session.uuid)  console.error('CheckSession failed: UUID mismatched'); return; 
            if (ses.user.role < conf['Permissions']['lm_user_query']) socket.emit('userQuery_fail','Insufficient permissions.'); return;             
            Query.users(col: col, where: where, range: range,function(err,res)
                if(!err)socket.emit('send_users',res);
                else socket.emit('failed_users',true); 
            );            
        );
    );
    socket.on('test',function(q)
        socket.emit('test',q);
    );
);

【问题讨论】:

多连接有什么问题? 如果只是多个连接,那将不是问题。问题在于,对于多个连接,所有 .emit() 命令都会运行多次。这意味着浪费了大量的时间/网络资源 听起来你要么发射到错误的东西,要么在错误的地方。 您需要向我们展示更多代码,因为您展示的内容不会创建多个连接,除非该代码位于页面中的多个位置。 我根据@jfriend00 的要求添加了更多代码。谢谢! 【参考方案1】:

尝试从 io 事物中删除 'new' 关键字。 您不应该在此处使用“新”,因为每次重新加载页面或新客户端连接时都会创建新实例。 所以,它应该看起来像: 服务器端:

var io = require('socket.io')(26265);

客户端:

var socket = io('http://localhost:26265');

我想这就是你要找的东西。

【讨论】:

有趣,我会在我回去工作时试一试。谢谢! 那是完全错误的。那是客户端连接;它需要一个实例。这要么失败,要么没有任何区别。 根据socket.io,我认为没有错。 Socket.IO 使用 1 个 websocket 传输其所有数据。因此,无需为每个客户端创建一个实例。无论如何,你比我更了解,因为我还在学习,sn-p 非常适合我。 感谢 KAKAN 的创意。我在没有定义新对象的情况下尝试了它。不幸的是,所有这一切似乎都是在每次构建套接字时重新定义会话。 “new”关键字允许构建函数的新“副本”及其原型。所以这没有用,不过谢谢你的想法!

以上是关于Socket.io 多连接的主要内容,如果未能解决你的问题,请参考以下文章

与 socket.io 相关的可扩展性问题

处理浏览器重新加载 socket.io

socket.io分布式

( Socket.io ) 一个socket连接多个房间

android studio连接io.socket:sokect.io-client服务器的条件

无法在docker中连接多个python socket.io