Nodejs中socket.io 1.0的reconnect问题,我测试发现重连后socket对象变化了

Nodejs中socket.io 1.0的reconnect问题,我测试发现重连后socket对象变化了

我的代码: 客户端: var io=socketIo.listen(server,{‘log level’: 2,‘pingTimeout’:300000,‘pingInterval’:1000}); 服务端:

var socket =io.connect('http://*********:3000',{'timeout': 300000,
        'reconnection': true,'reconnectionDelayMax':30000,'reconnectionDelay':1000});

我测试的逻辑:

首先禁掉一台测试机的网卡,3分钟后开启网卡,客户端重连成功,客户端触发"socket.on(‘reconnect’,function(){}"事件,服务端触发"io.on(‘connection’,function(socket){}"事件,之后服务端触发"socket.on(‘disconnect’,function(){}"事件(这次是把重连前的那个 socket断开了),

Connect..............1IpvXYapXibm0NzlAAAD
Connect..............uPlVSHeeZkOHt-8uAAAE
userList---2
1IpvXYapXibm0NzlAAAD---User4:disconnect.....

上面的日志可以看出:连进去2次,第一次 Connect是第一次进入,第二次是重连触发的Connect,之后把原来的socket断开了,disconnect是断开的第一次的socket,socket.id一样;

问题:难道是socket.io的重连机制是:先开个新的socket接连,再断开旧连接?而不是维护原来那个连接?


4 回复

Node.js 中 socket.io 1.0 的 reconnect 问题

问题描述

在使用 socket.io 1.0 进行客户端和服务端通信时,我发现当客户端断线后重新连接时,socket 对象发生了变化。这导致了一些困惑,因为我在处理重连逻辑时,希望保持原有的 socket 对象不变。

示例代码

下面是客户端和服务端的代码示例:

客户端代码

var socket = io.connect('http://localhost:3000', {
    timeout: 300000,
    reconnection: true,
    reconnectionDelayMax: 30000,
    reconnectionDelay: 1000
});

socket.on('connect', function () {
    console.log('Connected with ID:', socket.id);
});

socket.on('reconnect', function (attemptNumber) {
    console.log('Reconnected with ID:', socket.id);
});

socket.on('disconnect', function () {
    console.log('Disconnected with ID:', socket.id);
});

服务端代码

const io = require('socket.io')(server, {
    log: false,
    'log level': 2,
    pingTimeout: 300000,
    pingInterval: 1000
});

io.on('connection', function (socket) {
    console.log('New connection with ID:', socket.id);

    socket.on('disconnect', function () {
        console.log('Socket disconnected with ID:', socket.id);
    });
});

实际观察到的现象

当客户端断线并重新连接时:

  1. 客户端会触发 socket.on('reconnect', function() {}) 事件。
  2. 服务端会触发 io.on('connection', function(socket) {}) 事件。
  3. 服务端会立即触发 socket.on('disconnect', function() {}) 事件,断开旧的连接。
  4. 在日志中可以看到两个不同的 socket.id,表明 socket 对象确实发生了变化。

原因分析

socket.io 的重连机制是这样的:

  1. 当客户端断线后,它会尝试重新连接。
  2. 一旦重新连接成功,socket.io 会创建一个新的 socket 对象,并触发 reconnect 事件。
  3. 由于之前的连接已经断开,socket.io 会触发 disconnect 事件来断开旧的连接。

解决方案

如果你希望在重连后保持相同的 socket 对象,可以考虑以下几种方法:

  1. 手动管理连接状态:在客户端和服务端都记录连接状态,以便在重连时进行相应的处理。
  2. 自定义事件:在 reconnect 事件中触发自定义事件,通知应用层进行必要的状态更新。

通过这些方法,你可以更好地管理重连后的状态,确保应用的正常运行。


看看源码就晓得了,不是很长 可以用用engine.io,只实现了最基本的功能,其余功能想要的自己封装,比较方便简单 http://www.amoa400.com/p/analysis-engine.io

我自己找到了官方的解释: On a reconnection now instead of ‘reconnect’ another ‘connect’ event is fired instead.

http://socket.io/docs/migrating-from-0-9/#

在Node.js中使用socket.io 1.0时,客户端和服务端之间的重连机制确实会导致每次重新建立连接时生成一个新的socket对象。这是socket.io为了处理网络中断和其他连接异常情况而设计的一种策略。具体来说,当客户端与服务端之间的连接断开后,客户端会尝试重新连接,而每次重连都会生成一个新的socket实例。

示例代码

客户端代码

var socket = io.connect('http://yourserveraddress:3000', {
    timeout: 300000,
    reconnection: true,
    reconnectionDelayMax: 30000,
    reconnectionDelay: 1000
});

socket.on('connect', function () {
    console.log('Connected');
});

socket.on('reconnect', function (attemptNumber) {
    console.log('Reconnected after ' + attemptNumber + ' attempts');
});

socket.on('disconnect', function () {
    console.log('Disconnected');
});

socket.on('message', function (msg) {
    console.log('Message received: ', msg);
});

服务端代码

const io = require('socket.io')(server, {'log level': 2, 'pingTimeout': 300000, 'pingInterval': 1000});

io.on('connection', function (socket) {
    console.log('New client connected');

    socket.on('disconnect', function () {
        console.log('Client disconnected');
    });

    socket.on('message', function (msg) {
        socket.emit('message', 'Echo: ' + msg);
    });
});

解释

  1. 客户端

    • socket对象会在初次连接和每次重连时生成。
    • socket.on('reconnect', function () {...}) 用于监听重连事件。
    • 每次重连成功后,服务端会触发'connection'事件,并生成一个新的socket对象。
  2. 服务端

    • 服务端通过io.on('connection', function (socket) {...}) 监听连接事件。
    • 当客户端断开并重新连接时,服务端会认为这是一个新的连接,并生成一个新的socket对象。

因此,如果你需要跟踪用户的连接状态,可以在客户端和服务端分别实现一些逻辑来管理这些socket对象的状态。

回到顶部