调用 .disconnect() 后如何重新连接
Posted
技术标签:
【中文标题】调用 .disconnect() 后如何重新连接【英文标题】:How to reconnect after you called .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 但我不确定是否是那个。试过了,它多次调用我的方法..
【参考方案1】:
最新socket.io中的标准做法是:
socket.on('disconnect', function()
socket.socket.reconnect();
)
这是我一直在我的应用程序中使用的,效果很好。它还确保套接字在服务器出现故障时不断尝试重新连接,并最终在服务器重新联机时重新连接。
在您的情况下,您需要确保两件事:
-
您只创建一次套接字。请勿多次致电
socket = io.connect(...)
。
您只需设置一次事件处理 - 否则它们将被多次触发!
因此,当您想重新连接客户端时,请致电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();
让您重新连接。
【讨论】:
以上是关于调用 .disconnect() 后如何重新连接的主要内容,如果未能解决你的问题,请参考以下文章