【问题标题】:How to reconnect after you called .disconnect()调用 .disconnect() 后如何重新连接
【发布时间】:2012-03-24 19:53:18
【问题描述】:

问题:在您发出手册.disconnect() 后如何将客户端重新连接到服务器?

在我当前的项目中,当用户从会话中注销时,我需要断开客户端与服务器的连接。我做了一个socket.disconnect() 来成功断开连接。服务器从会话中删除了用户。

一段时间后,用户决定再次登录,但是socket.io拒绝连接。

我很清楚 Socket.IO 已经实现了重新连接算法,但显然这是不同的情况。

下面是我进行连接的一段代码。在第二次触发此代码块时,创建了对象 socket,但没有从该对象触发 connect

//Start the socket
var socket = io.connect(SOCKET_IO_URL);
socket.on('connect', function() {
    me.fireEvent('connect');
    socket.emit('register', {
        hashed_identifier: hashed_identifier,
        account_id: account_id
    });
});

socket.on('ready', function() {
    me.ready = true;
    me.log('Handshake done. Listening for new data');
});

socket.on('data', function(data) {
    me.fireEvent('data', data);
    //Tells server we received it
    socket.emit('data', {ack: 1});
});

socket.on('disconnect', function() {
    me.fireEvent('disconnect');
});

更新:应@Tony 的要求

其实整个东西都包裹在Sencha Touch 2.0下,但我相信和ST2.0无关

这是我的数据类。该类的用法是当用户登录时,该类将被初始化。并且在用户注销时,系统会调用该类中的disconnect()方法。

当用户再次登录时,这个类再次被初始化,但有趣的是套接字以某种方式保留了它之前的所有事件和会话。

/**
* Serve as interface to wait for data communication in between server and client
*/
Ext.define('go.module.connect.Data', {

    mixins: {
        observable: 'Ext.mixin.Observable'
    },

    config: {
        account: null
    },

    ready: false,

    socket: null,

    constructor: function(cfg) {
        var me = this,
            hashed_identifier = Sha1.hash(go.__identifier);


        me.initConfig(cfg);

        var account_id = me.getAccount().get('id');

        //Start the socket
        var socket = io.connect(SOCKET_IO_URL);
        socket.on('connect', function() {
            console.log('connect');
            me.fireEvent('connect');
            socket.emit('register', {
                hashed_identifier:hashed_identifier,
                account_id: account_id
            });
        });

        socket.on('ready', function() {
            me.ready = true;
            me.log('Handshake done. Listening for new data');
        });

        socket.on('data', function(data) {
            me.fireEvent('data', data);
            //Tells server we received it
            socket.emit('data', {ack: 1});
        });

        socket.on('disconnect', function() {
            me.fireEvent('disconnect');
        });

        console.log(socket);
        if (!socket.socket.connected){
            socket.socket.reconnect();
        }


        me.socket = socket;


        me.callParent([cfg]);
    },

    disconnect: function() {
        this.socket.disconnect();
        this.socket.removeAllListeners();
        this.socket.socket.removeAllListeners();
    },

    log: function(msg) {
        console.log('@@ Connect: '+msg);
    }
});

以下是我的 console.log 结果:

下面是我的 node.js 调试窗口

我认为这个有趣的场景的根本原因是之前附加的connect 事件监听器没有被彻底删除。我应该如何删除它?我应该使用once 吗?或者我也应该指定监听器函数。我认为removeAllListeners() 足以完成这项任务。

【问题讨论】:

  • 你的register 事件意味着login,对吧?
  • 登录和注册的排序。但是当我在连接回调中执行 console.log 时,我什么也没得到。当这段代码第二次运行时,套接字对象被创建但从不触发连接事件。创建的socket对象有socket.socket.connected false。我看到重新连接方法出现在 socket.socket 但我不确定是否是那个。试过了,它多次调用我的方法..

标签: javascript node.js websocket socket.io


【解决方案1】:

最新socket.io中的标准做法是:

socket.on('disconnect', function() {
    socket.socket.reconnect();
})

这是我一直在我的应用程序中使用的,效果很好。它还确保套接字在服务器出现故障时不断尝试重新连接,并最终在服务器重新联机时重新连接。

在您的情况下,您需要确保两件事:

  1. 您只创建一次套接字。请勿多次致电socket = io.connect(...)
  2. 您只需设置一次事件处理 - 否则它们将被多次触发!

因此,当您想重新连接客户端时,请致电socket.socket.reconnect()。您还可以在 FireFox 和 Chrome 的浏览器控制台中对此进行测试。

【讨论】:

  • 断开连接后,我执行了 socket.socket.reconnect() 但令人惊讶的是我被多个connect 解雇了。即使我设法运行了removeAllListeners(),但仍然触发了多个connect。解决方案?
  • @LionelChan 您能否发布导致多个连接事件的更新代码?
  • 啊,是的 io.connect 被解雇了两次。但我很惊讶他们如何很好地保留会议..
  • 我通过确保事情只运行一次来​​解决我的问题 - 结构改变了,现在它工作正常。谢谢!
  • 据我所知,removeAllListeners 至少需要一个参数——触发器。对于 socket.io,您需要为每个事件调用它,例如 removeAllListeners('connect') 等(抱歉,找不到参考)。很高兴您解决了问题!
【解决方案2】:

socket.io v2.0(当前)

对于寻找我最新版本的人们,请找到以下文档摘录:

手动重新连接:

socket.on('disconnect', () => {
  socket.open();
});

【讨论】:

    【解决方案3】:

    socket.io-client v2.2.0

    import io from "socket.io-client"
    
    var socket = io(url)  // initial connection
    
    const reconnect = () => {
      if(!socket.connected) {
        socket = io(url)  // reconnects to a new socket
      }
    }
    

    【讨论】:

      【解决方案4】:

      我正在使用 socket.io 1.4.5 这样做,现在它似乎可以工作:

      var app = {
          socket: null,
          connect: function() {
            // typical storing of reference to 'app' in this case
            var self = this;
            // reset the socket
            // if it's not the first connect() call this will be triggered
            // I hope this is enough to reset a socket
            if( self.socket ) {
              self.socket.disconnect();
              delete self.socket;
              self.socket = null;
            }
            // standard connectiong procedure
            self.socket = io.connect( 'http://127.0.0.1:3000', { // adapt to your server
              reconnection: true,             // default setting at present
              reconnectionDelay: 1000,        // default setting at present
              reconnectionDelayMax : 5000,    // default setting at present
              reconnectionAttempts: Infinity  // default setting at present
            } );
            // just some debug output
            self.socket.on( 'connect', function () {
              console.log( 'connected to server' );
            } );
            // important, upon detection of disconnection,
            // setup a reasonable timeout to reconnect
            self.socket.on( 'disconnect', function () {
              console.log( 'disconnected from server. trying to reconnect...' );
              window.setTimeout( 'app.connect()', 5000 );
            } );
          }
      } // var app
      
      
      app.connect();
      

      【讨论】:

        【解决方案5】:

        您可以按照客户端配置重新连接。

         // for socket.io version 1.0
        io.connect(SERVER_IP,{'forceNew':true };
        

        【讨论】:

          【解决方案6】:

          在我看来,这就是您处理断开连接的方式... 使用 socket.io - v1.1.0 为我工作

          走错路了……

          var sock = io( '/' );
          sock.on( 'connect', function(x) { console.log( 'Connected', x ); } );
          // now we disconnect at some point:
          sock.disconnect();
          // now we try to reconnect...
          sock.connect()
          // or    
          sock.reconnect();
          // - both seem to create the new connection in the debugger, all events are missing though
          

          正确的方法...

          // As above with 3 extra characters, everything functions as expected...
          //events fire properly...
          sock.io.disconnect();
          // consequently i'm also using (for consitency)
          sock.io.reconnect();
          // sock.connect() still seems to work however.
          

          【讨论】:

            【解决方案7】:
            socket.socket.connect();
            

            让您重新连接。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-12-29
              • 1970-01-01
              • 1970-01-01
              • 2012-11-27
              • 2017-12-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多