Nodejs socket.io 无限 timeout

Nodejs socket.io 无限 timeout

服务端 io.sockets.on(‘connection’,function(socket){

socket.on(‘geta’,function(data){ io.sockets.emit(‘dd’,{tt:58}); });

socket.on(‘getb’,function(data){ io.sockets.emit(‘ee’,{bbss:“xxdd.com”}); });

socket.on(‘disconnect’,function(){ console.log(“断开了”); io.sockets.emit(‘lossLine’,{lossLine:111}); }); });

客户端 var socket = io.connect(“http://xx.yy.com”); socket.on(‘connect’,function(){ socket.emit(‘geta’,{itemId:itemId}); socket.on(‘geta’,function(data){

       });
       socket.on('lossLine',function(data){
              console.log(data);
       });

});

linux 服务器上

4 debug - setting poll timeout debug - discarding transport debug - cleared close timeout for client cmDBXWPwZSXHxHtLlpdE debug - clearing poll timeout debug - xhr-polling writing 8:: debug - set close timeout for client cmDBXWPwZSXHxHtLlpdE debug - xhr-polling closed due to exceeded duration debug - setting request GET /socket.io/1/xhr-polling/cmDBXWPwZSXHxHtLlpdE?t=1375087802876 debug - setting poll timeout debug - discarding transport debug - cleared close timeout for client cmDBXWPwZSXHxHtLlpdE debug - clearing poll timeout debug - xhr-polling writing 8:: debug - set close timeout for client cmDBXWPwZSXHxHtLlpdE debug - xhr-polling closed due to exceeded duration

页面firebug 一直 自动重连 打开页面 要过二十多秒 才收到数据

页面上写了 一个onlick方法 socket.emit(‘getb’,{itemId:itemId}); 接受都蛮正常的


4 回复

Node.js Socket.io 无限 Timeout

问题描述

在使用 Node.js 和 Socket.io 的时候,客户端连接到服务器后会不断出现自动重连的情况,并且页面加载时需要等待大约20秒才能接收到数据。此外,服务器端的日志显示存在一些超时和传输丢弃的记录。

分析

从日志中可以看到 xhr-polling closed due to exceeded duration 的错误信息,这表明客户端和服务器之间的长轮询(XHR Polling)连接因为超时而关闭了。这种情况下,Socket.io 会尝试重新连接,导致页面上的连接不稳定。

解决方案

为了防止这种情况,可以调整 Socket.io 的配置来增加超时时间,并优化连接管理逻辑。

服务端代码调整

首先,确保服务端正确处理连接和断开事件:

const io = require('socket.io')(server);

io.sockets.on('connection', function(socket) {
    console.log('新客户端连接');

    socket.on('geta', function(data) {
        io.sockets.emit('dd', { tt: 58 });
    });

    socket.on('getb', function(data) {
        io.sockets.emit('ee', { bbss: "http://xxdd.com" });
    });

    socket.on('disconnect', function() {
        console.log("客户端断开");
        io.sockets.emit('lossLine', { lossLine: 111 });
    });
});
客户端代码调整

然后,在客户端添加更多的调试信息,并调整超时设置:

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect('http://xx.yy.com', {
        transports: ['xhr-polling'], // 使用 XHR-Polling 连接
        'force new connection': true, // 强制创建新的连接
        reconnectionDelayMax: 10000, // 最大重连延迟时间
        timeout: 20000 // 增加超时时间
    });

    socket.on('connect', function() {
        console.log('已连接');
        socket.emit('geta', { itemId: itemId });

        socket.on('geta', function(data) {
            console.log('接收到了 geta 数据:', data);
        });

        socket.on('lossLine', function(data) {
            console.log('连接丢失:', data);
        });
    });

    document.getElementById('myButton').onclick = function() {
        socket.emit('getb', { itemId: itemId });
    };
</script>

总结

通过上述调整,我们可以增加连接的稳定性和响应速度。特别是增加 timeoutreconnectionDelayMax 参数,可以帮助减少频繁的重连情况。同时,确保客户端和服务端正确处理连接和断开事件,以便及时更新状态信息。


怪了, 以前跑 Demo 是没在问题的呀, 是不是 Firefox 的问题, Chrome 呢?

解决了 nginx 版本太低

根据你的描述,问题可能出在Socket.IO的长轮询(xhr-polling)传输方式上。长轮询默认有一个超时时间,当超过这个时间没有收到响应时,会自动关闭连接并重新连接,导致页面上看到频繁的重连现象。

你可以尝试使用WebSocket传输方式,它不会出现超时问题,并且性能更好。如果需要支持老浏览器,可以配置Socket.IO来优先使用WebSocket,如果不可用再降级为其他传输方式。

修改服务端配置

确保你的服务端初始化Socket.IO时指定传输优先级:

const io = require('socket.io')(server, {
    transports: ['websocket', 'polling'] // 配置优先使用WebSocket
});

修改客户端连接

客户端连接时可以设置重连策略,避免频繁重连影响用户体验:

var socket = io.connect("http://xx.yy.com", {
    reconnection: true,
    reconnectionDelay: 1000, // 重连延迟时间
    reconnectionAttempts: 5 // 最大重连次数
});

socket.on('connect', function() {
    console.log("Connected");
    socket.emit('geta', {itemId: itemId});
    
    socket.on('geta', function(data) {
        console.log("Data received:", data);
    });

    socket.on('lossLine', function(data) {
        console.log("Lost line:", data);
    });
});

示例代码

以下是完整的服务端和客户端代码示例:

服务端代码

const io = require('socket.io')(server, {
    transports: ['websocket', 'polling']
});

io.sockets.on('connection', function(socket) {
    socket.on('geta', function(data) {
        io.sockets.emit('dd', { tt: 58 });
    });

    socket.on('getb', function(data) {
        io.sockets.emit('ee', { bbss: "http://xxdd.com" });
    });

    socket.on('disconnect', function() {
        console.log("断开了");
        io.sockets.emit('lossLine', { lossLine: 111 });
    });
});

客户端代码

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket = io.connect("http://xx.yy.com", {
        reconnection: true,
        reconnectionDelay: 1000,
        reconnectionAttempts: 5
    });

    socket.on('connect', function() {
        console.log("Connected");
        socket.emit('geta', {itemId: itemId});
        
        socket.on('geta', function(data) {
            console.log("Data received:", data);
        });

        socket.on('lossLine', function(data) {
            console.log("Lost line:", data);
        });
    });

    function handleButtonClick() {
        socket.emit('getb', {itemId: itemId});
    }
</script>

<button onclick="handleButtonClick()">Send GetB</button>

这样修改后,应该能够减少频繁重连的现象,并提高连接的稳定性。

回到顶部