简体   繁体   English

如何自动重新连接到XMPP服务器?

[英]How to auto-reconnect to XMPP server?

I have an application which is supposed to keep permanent connection to a XMPP server. 我有一个应该与XMPP服务器保持永久连接的应用程序。 But every 2 or 3 days, it disconnects, and can't reconnect automatically with ReconnectionManager as it is supposed to do. 但是每隔2或3天,它就会断开连接,并且无法像预期的那样自动与ReconnectionManager重新连接。

What could I do to see what is happening and/or to correct this ? 我该怎么做才能查看正在发生的事情和/或对此进行更正?

2018-09-20 07:06:10.887 -  WARN - o.j.smack.AbstractXMPPConnection         : Connection closed with error
java.net.SocketException: Connexion terminée par expiration du délai d'attente (Read failed)
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
        at sun.security.ssl.InputRecord.read(InputRecord.java:503)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940)
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.read1(BufferedReader.java:212)
        at java.io.BufferedReader.read(BufferedReader.java:286)
        at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:2992)
        at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
        at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1144)
        at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1177)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:956)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:971)
        at java.lang.Thread.run(Thread.java:748)

Here is my Connection conf (Spring java-style config) : 这是我的Connection conf(Spring Java风格的配置):

  @Bean("xmppConnection")
  public XmppConnectionFactoryBean xmppConnectionFactoryBean() {

    XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
    configBuilder.setUsernameAndPassword(appProperties.getXmpp().getUsername(), appProperties.getXmpp().getPassword());
    configBuilder.setServiceName(appProperties.getXmpp().getServiceName());
    configBuilder.setHost(appProperties.getXmpp().getHost());
    int port = appProperties.getXmpp().getPort();
    if (port != 0) {
      configBuilder.setPort(port);
    }
    int timeout = appProperties.getXmpp().getTimeout();
    if (timeout != 0) {
      configBuilder.setConnectTimeout(timeout);
    }
    configBuilder.setDebuggerEnabled(appProperties.getXmpp().isDebuggerEnabled());
    XMPPTCPConnectionConfiguration config = configBuilder.build();

    XmppConnectionFactoryBean connectionFactoryBean = new XmppConnectionFactoryBean();
    connectionFactoryBean.setConnectionConfiguration(config);
    connectionFactoryBean.setSubscriptionMode(null);

    return connectionFactoryBean;
  }

And here is where the connection is used in Spring Integration conf : 这是Spring Integration conf中使用连接的地方:

<int-xmpp:inbound-channel-adapter id="xmppInboundAdapter" channel="xmppInbound" xmpp-connection="xmppConnection" auto-startup="true" />

UPDATE : To audit the issue, I've just added a listener to xmppConnection : 更新:要审核此问题,我刚刚向xmppConnection添加了一个侦听器:

  @Bean("xmppConnection")
  public XMPPConnection xmppConnection(XmppConnectionFactoryBean xmppConnectionFactoryBean) throws Exception {
    XMPPConnection xmppConnection = xmppConnectionFactoryBean.getObject();
    xmppConnection.addConnectionListener(new ConnectionListener() {

      @Override
      public void reconnectionSuccessful() {
        logger.info("Successfully reconnected to the XMPP server.");
      }

      @Override
      public void reconnectionFailed(Exception arg0) {
        logger.info("Failed to reconnect to the XMPP server.");
      }

      @Override
      public void reconnectingIn(int seconds) {
        logger.info("Reconnecting in " + seconds + " seconds.");
      }

      @Override
      public void connectionClosedOnError(Exception arg0) {
        logger.error("Connection to XMPP server was lost.");
      }

      @Override
      public void connectionClosed() {
        logger.info("XMPP connection was closed.");
      }

      @Override
      public void connected(XMPPConnection connection) {
        logger.info("Connected to XMPP server.");        
      }

      @Override
      public void authenticated(XMPPConnection connection, boolean resumed) {
        logger.info("Authenticated to XMPP server.");        
      }
    });

    return xmppConnection;

  }

UPDATE 2 : now with the audit activated, I can see : 更新2:现在启动了审计,我可以看到:

2018-10-03 07:29:39.442 - ERROR - f.e.r.l.i.xmpp.config.XmppManagerConfig  : Connection to XMPP server was lost.

but never "Reconnecting in" or "Failed to reconnect". 但绝不要“重新连接”或“无法重新连接”。

Hi I hope you are using latest version of smack 4.3.0 嗨,我希望您正在使用最新版本的smack 4.3.0

By default Smack will try to reconnect the connection in case it was abruptly disconnected. 默认情况下,如果突然断开连接,Smack将尝试重新连接。 The reconnection manager will try to immediately reconnect to the server and increase the delay between attempts as successive reconnections keep failing. 重新连接管理器将尝试立即重新连接到服务器,并增加尝试之间的延迟,因为连续的重新连接持续失败。

In case you want to force a reconnection while the reconnection manager is waiting for the next reconnection, you can just use AbstractXMPPConnection#connect() and a new attempt will be made. 如果要在重新连接管理器等待下一次重新连接时强制重新连接,则可以只使用AbstractXMPPConnection#connect()进行新的尝试。 If the manual attempt also failed then the reconnection manager will still continue the reconnection job. 如果手动尝试也失败,则重新连接管理器仍将继续进行重新连接作业。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM