Smack:ReconnectionManager 在重新连接时发送重复的登录请求

Posted

技术标签:

【中文标题】Smack:ReconnectionManager 在重新连接时发送重复的登录请求【英文标题】:Smack: ReconnectionManager sends duplicate login requests while reconnecting 【发布时间】:2016-06-20 18:03:26 【问题描述】:

我正在使用 Smack(4.1.7) 创建一个 android Xmpp 客户端。在使用 ReconnectionManager 实现自动重新连接功能时,我发现库发送了重复的登录请求。因此,第二次重新连接被服务器拒绝并出现错误 - Client is already logged in

这是来自 Smack 的 XML 转储:

6-20 15:42:37.704 26369-26612/in.gappi.gappichat D/SMACK: XMPPConnection closed due to an exception (0)
06-20 15:42:37.714 26369-26612/in.gappi.gappichat W/System.err: java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
06-20 15:42:37.714 26369-26612/in.gappi.gappichat W/System.err:     at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:592)
06-20 15:42:37.714 26369-26612/in.gappi.gappichat W/System.err:     at libcore.io.IoBridge.recvfrom(IoBridge.java:556)
.....
.....
06-20 15:42:38.714 26369-26829/in.gappi.gappichat D/GappiXmpp: Reconnecting 10
06-20 15:42:38.714 26369-26829/in.gappi.gappichat D/SMACK: XMPPConnection (0) will reconnect in 10
.....
06-20 15:42:48.724 26369-26829/in.gappi.gappichat D/GappiXmpp: Reconnecting 0
06-20 15:42:48.724 26369-26829/in.gappi.gappichat D/SMACK: XMPPConnection (0) will reconnect in 0
06-20 15:42:48.894 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='gappi.in' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='9739937980@gappi.in' xml:lang='en'>
06-20 15:42:48.984 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='11040239326876846172' from='gappi.in' version='1.0' xml:lang='en'>
06-20 15:42:48.984 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='PXc8x7mNN6cEIZgjsEishHW4d3E='/><register xmlns='http://jabber.org/features/iq-register'/><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>DIGEST-MD5</mechanism><mechanism>SCRAM-SHA-1</mechanism><mechanism>PLAIN</mechanism><mechanism>X-OAUTH2</mechanism></mechanisms></stream:features>
06-20 15:42:48.994 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>biwsbj05NzM5OTM3OTgwLHI9QncuaHNmXV8lOGAyInQzTEJacnpkXmBPVCR3Rl90J0M=</auth>
06-20 15:42:49.094 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1Cdy5oc2ZdXyU4YDIidDNMQlpyemReYE9UJHdGX3QnQ0RsUkhLTTRJU2V5ZG1LNGtSRThva3c9PSxzPUpJemJtbXAxaExzRFNZV042M1EyK0E9PSxpPTQwOTY=</challenge>
06-20 15:42:49.264 26369-26388/in.gappi.gappichat I/art: Background partial concurrent mark sweep GC freed 90062(4MB) AllocSpace objects, 20(540KB) LOS objects, 32% free, 33MB/49MB, paused 1.826ms total 137.089ms
06-20 15:42:49.564 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>Yz1iaXdzLHI9QncuaHNmXV8lOGAyInQzTEJacnpkXmBPVCR3Rl90J0NEbFJIS000SVNleWRtSzRrUkU4b2t3PT0scD16UXpxR2xVeDArTnF1M1lERkxhN2lubXphNnc9</response>
06-20 15:42:49.654 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>dj1vdHAxTGtUVVZMZW1GdEVLOXdmZWlqQTdWK1E9</success>
06-20 15:42:49.654 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='gappi.in' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='9739937980@gappi.in' id='11040239326876846172' xml:lang='en'>
06-20 15:42:49.654 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <resume xmlns='urn:xmpp:sm:3' h='2' previd='g2gCbQAAAAVTbWFja2gDYgAABbpiAAbIgmIAAAIt'/>
06-20 15:42:49.734 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='5567512457513756075' from='gappi.in' version='1.0' xml:lang='en'>
06-20 15:42:49.734 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <stream:features><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='PXc8x7mNN6cEIZgjsEishHW4d3E='/><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/><session xmlns='urn:ietf:params:xml:ns:xmpp-session'><optional/></session><sm xmlns='urn:xmpp:sm:2'/><sm xmlns='urn:xmpp:sm:3'/><csi xmlns='urn:xmpp:csi:0'/></stream:features>
06-20 15:42:49.814 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <resumed xmlns='urn:xmpp:sm:3' h='2' previd='g2gCbQAAAAVTbWFja2gDYgAABbpiAAbIgmIAAAIt'/>
06-20 15:42:49.814 26369-26829/in.gappi.gappichat D/SMACK: User logged (0): 9739937980@gappi.in:5222/Smack
06-20 15:42:49.814 26369-27616/in.gappi.gappichat D/SMACK: RECV (0): <r xmlns='urn:xmpp:sm:3'/>
06-20 15:42:49.814 26369-26829/in.gappi.gappichat D/SMACK: XMPPConnection authenticated (0) and resumed
06-20 15:42:49.814 26369-27615/in.gappi.gappichat D/SMACK: SENT (0): <a xmlns='urn:xmpp:sm:3' h='2'/>
06-20 15:42:49.824 26369-26829/in.gappi.gappichat D/SMACK: XMPPConnection connected (0)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat D/GappiXmpp: ReconnectionFailed!
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err: org.jivesoftware.smack.SmackException$AlreadyLoggedInException: Client is already logged in
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.tcp.XMPPTCPConnection.throwAlreadyLoggedInExceptionIfAppropriate(XMPPTCPConnection.java:358)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:452)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:414)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection.java:863)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.AbstractXMPPConnection.connect(AbstractXMPPConnection.java:364)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at org.jivesoftware.smack.ReconnectionManager$2.run(ReconnectionManager.java:241)
06-20 15:42:49.834 26369-26829/in.gappi.gappichat W/System.err:     at java.lang.Thread.run(Thread.java:818)

有时06-20 15:42:48.89406-20 15:42:49.654 会发送两个不同的&lt;stream/&gt; 节,这最终会导致稍后发生异常。

这种行为有什么理由吗?我的客户端 xmpp 代码如下所示:

  XMPPTCPConnectionConfiguration connConfig = XMPPTCPConnectionConfiguration.builder().setHost(serverAddress)
            .setPort(5222).setDebuggerEnabled(true).setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
            .setUsernameAndPassword(loginUser, passwordUser).setServiceName(serverAddress).build();
    XMPPTCPConnection.setUseStreamManagementDefault(true);
    XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
    connection = new XMPPTCPConnection(connConfig);
    connection.setUseStreamManagement(true);
    connection.setUseStreamManagementResumption(true);

    XMPPConnectionListener connectionListener = new XMPPConnectionListener();
    connection.addConnectionListener(connectionListener);
    connection.setPacketReplyTimeout(10000);
    connection.addStanzaAcknowledgedListener(new StanzaListener() 
        @Override
        public void processPacket(Stanza packet) throws SmackException.NotConnectedException 
            String id = packet.getStanzaId();
            if (StringUtils.isNullOrEmpty(id)) 
                return;
            
            stanzaAcknowledged(id);
        
    );

    ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
    reconnectionManager.setEnabledPerDefault(true);
    reconnectionManager.enableAutomaticReconnection();

【问题讨论】:

关于这个主题的任何更新?我面临着类似的问题。当我尝试重新连接连接时,突然出现 Stream 错误冲突,提示客户端已登录。 【参考方案1】:

有时 06-20 15:42:48.894 和 06-20 15:42:49.654 两个 发送不同的节,最终导致 稍后例外。

不,这不是导致异常的原因,也不是异常的原因。您会看到两个 open 标记,这是完全正常的(参见 RFC 6120)。该异常只是告诉您 ReconnectionManager 无法完成其工作,因为连接已经过身份验证。

【讨论】:

即使引发异常,客户端仍连接到服务器并可以发送/接收消息。问题是“已经登录”异常会触发“reconnectionFailed”回调。那么这是 Smack 库的问题吗?

以上是关于Smack:ReconnectionManager 在重新连接时发送重复的登录请求的主要内容,如果未能解决你的问题,请参考以下文章

Smack 异常 - 由我的 Java 安装或 Smack 引起

如何为 xmpp 实现 smack

smack / ejabberd 连接超时

无法得到 smack 的回应

如何从 aSmack 迁移到 Smack

android中的XMPP连接使用smack