当谷歌浏览器中有很多 websocket 连接时,socket io 会中断

Posted

技术标签:

【中文标题】当谷歌浏览器中有很多 websocket 连接时,socket io 会中断【英文标题】:Socket io breaks when a lot websocket connections in google chrome 【发布时间】:2020-11-13 13:10:52 【问题描述】:

我在 google chrome 浏览器中创建了 60 个到 socket.io 服务器的客户端连接。 服务器在特定时间向客户端发送屏幕截图。并且一些 websocket 连接,即 socket.io 的子协议被破坏,因此大约 1-4 个 chrome 选项卡的连接被关闭。我尝试增加 pingTimeout,它只有助于克服 tcp 传输关闭问题(这个问题我也有),但这个解决方案无助于解决发送屏幕截图的问题。

在我看来,谷歌浏览器一次不能支持大约 50-60 个标签,因为 CPU 和 RAM 增加到最大值,因为向 60 个客户端发送屏幕截图(每个客户端有 2 个 websocket 连接:第一个用于简单消息,第二个用于图形(发送屏幕截图)),因此 chrome 关闭了一些 websocket 连接。

这里是服务器socket io的部分代码:

// server
this.http = this._createHttpServer(sslCert, sslKey);

this.io = socketIo(this.http, 
    'pingTimeout': 180000,
    'pingInterval': 60000
);

const jwtAuth = socketioJwt.authorize(
     secret: jwtSecret,
     timeout: 15000
);

this.io.on('connection', (socket) => 
    socket.once('authenticate', (data) => 
        socket.rawAuthData = data;
    );
    jwtAuth(socket);
);


// client
var connOptions = 
    "reconnectionAttempts": 2
;
var socket = io(options.url, connOptions);
socket.on('connect', function() 
    if (options.token) 
        socket.emit('authenticate', token: options['token'], tag : tag);

        socket.on('authenticated', function() 
            ctx.printLog('Authorized. Waiting for handshake');
            socket.once('tunnel-handshake', function() 
                ctx.printLog('handshake received! connection is ready');
                processConnected();
            );
        ).on('unauthorized', function(msg) 
            ctx.printLog("Authorization failed: " + JSON.stringify(msg.data));
            eventHandlers.onerror( code: ctx.ERROR_CODE.INVALID_TOKEN);
        );
     else 
        processConnected();
    
);

socket.on('reconnect_failed', eventHandlers.onerror.bind(this, code: 1, reason: "Reconnection failed"));
socket.on('disconnect', eventHandlers.onclose);
socket.on('error', eventHandlers.onerror);

是否存在任何想法,原因可能是什么?这个问题是否存在任何解决方案? 是 google chrome 问题还是 socket.io 选项问题? 谢谢

【问题讨论】:

【参考方案1】:

将 socket.io 更改为 3.0 版本无法解决问题。 socket.io v3.0engine.io v4.0。 engine.io v4.0的Next information in release notes描述了这个问题(《心跳机制反转》标题):

我们收到了很多用户的报告,他们遇到由于 ping 超时而随机断开连接,即使他们的 Internet 连接已启动且远程服务器可访问。需要注意的是,在这种情况下客户端会立即重新连接,但这仍然是一个烦人的问题。

经过分析,似乎是因为 客户端。这些计时器用于乒乓机制 有助于确保服务器和客户端之间的连接是 仍然健康。客户端的延迟意味着客户端发送了 ping数据包太晚,服务器认为连接 已关闭。

这就是为什么 ping 数据包现在将由服务器发送,并且 客户端将使用 pong 数据包进行响应。

但是将 pingTimeout 和 pingInterval 增加到 1073741823 值可以解决问题。

【讨论】:

以上是关于当谷歌浏览器中有很多 websocket 连接时,socket io 会中断的主要内容,如果未能解决你的问题,请参考以下文章

网页打印时提示websocket没有准备好

websocket不断断开连接

谷歌浏览器自动填充删除背景图片

谷歌浏览器Chrome错误提示Flash过期怎么办(转)

谷歌HTTP负载平衡器无法升级的Web Socket连接

Android浏览器中的假websocket功能