关于Nodejs中socket.io 总是自动断开的问题

关于Nodejs中socket.io 总是自动断开的问题

我最近在写一个基于socket.io聊天室,我遇到了两个比较严重的问题。

1.并不是每次连接断开,都会触发服务端的disconnect事件,比如我开一个服务端,在快速刷新的时候, io.sockets 内部统计在线人数的属性(io.sockets.server.eio.clientsCount 就是这个属性)的值会不断递增,而实际是只有一个客户端连接了服务器端, 而统计到的在线人数要多一些。而内存里面也多了很多客户端socket,这些都是没有人在线的。根据我应用上线的情况来看,不只是快速刷新的时候会出现这种情况。

2.在某些手机浏览器上面,会自动断开。然后刷新一次就不会再自动断开了。

ps:应用地址 http://coocoo.epoching.com/

希望各位大神可以帮忙解决一下


3 回复

关于Nodejs中socket.io总是自动断开的问题

我最近在开发一个基于socket.io的聊天室时,遇到了两个比较严重的问题。

问题一:客户端连接断开后,服务端未及时触发disconnect事件

当我在快速刷新页面或者多次打开关闭浏览器窗口时,发现服务端并没有每次都正确地触发disconnect事件。这导致了io.sockets.server.eio.clientsCount属性的值不断增加,但实际上只有单一客户端连接到了服务器。这意味着内存中出现了大量无用的socket对象,尽管这些socket并没有实际的用户在线。

解决方案

为了确保在客户端断开连接时能正确触发disconnect事件,你需要在客户端和服务端都进行相应的处理。下面是一个简单的示例:

// 服务端代码
const io = require('socket.io')(server);

io.on('connection', (socket) => {
    console.log('New client connected');
    
    socket.on('disconnect', () => {
        console.log('Client disconnected');
        // 可以在这里清理一些资源或记录日志
    });
});

// 客户端代码
let socket;
try {
    socket = io.connect('http://coocoo.epoching.com/');
} catch (error) {
    console.error("Socket connection failed:", error);
}

window.addEventListener('beforeunload', () => {
    if (socket) {
        socket.disconnect();
    }
});

问题二:在某些手机浏览器上,socket连接自动断开

在某些移动设备的浏览器上,我发现socket连接会自动断开,但当用户刷新页面后,连接问题就解决了。

解决方案

这种现象可能是由于移动设备的网络环境不稳定,或者浏览器自身的限制导致的。为了解决这个问题,你可以尝试增加心跳包的发送频率,以保持连接的活跃状态:

// 服务端代码
const io = require('socket.io')(server, {
    transports: ['websocket'],
    pingInterval: 25000, // 每25秒发送一次心跳包
    pingTimeout: 60000   // 60秒内没有响应则认为连接断开
});

// 客户端代码
let socket;
try {
    socket = io.connect('http://coocoo.epoching.com/', {
        transports: ['websocket']
    });
} catch (error) {
    console.error("Socket connection failed:", error);
}

通过调整心跳包参数,可以提高连接的稳定性,特别是在移动设备上。


希望以上建议能够帮助你解决问题。如果还有其他疑问,欢迎继续交流!


可以加我qq 1405491181

关于你提到的两个问题,可以通过以下几个步骤来解决:

问题1: disconnect事件未触发且客户端数量统计不准确

这可能是由于socket.io的客户端和服务器之间的重连机制导致的。为了确保每个客户端只被计数一次,你可以使用disconnect事件来正确处理断开连接的逻辑。同时,你可以利用socket.io的连接事件来更新在线用户列表。

示例代码:

服务端代码 (Node.js + socket.io):

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

io.on('connection', function(socket) {
    console.log("A user connected");

    socket.on('disconnect', function() {
        console.log("User disconnected");
        // 在这里从在线用户列表中移除该socket
    });
});

问题2: 某些手机浏览器自动断开连接

这个问题可能与网络环境或浏览器的限制有关。可以尝试以下方法来改善客户端的行为:

  1. 调整心跳包间隔socket.io默认的心跳包间隔可能在某些环境中不适用。你可以通过修改pingTimeoutpingInterval来优化客户端与服务器的连接稳定性。

  2. 检查浏览器兼容性: 确保你的socket.io版本兼容你正在使用的浏览器版本。某些旧版本的浏览器可能不支持WebSocket等特性。

示例代码:

const io = require('socket.io')(server, {
    pingTimeout: 60000,
    pingInterval: 25000
});

通过上述调整,你可以更好地管理客户端连接,并减少不必要的资源消耗。如果问题仍然存在,建议深入检查具体的浏览器和网络环境,以确定是否有其他特定因素影响连接稳定性。

回到顶部