asmack 中的 ReconnectionManager

4

我有一个关于Android的项目,需要使用asmack库来实现实时聊天。

关键特性是重新连接机制,也就是说,当网络连接断开时,我的应用程序可以自动重连。

这里是我的代码片段:

ConnectionConfiguration connConfig = new ConnectionConfiguration(HOST, PORT);
connConfig.setSASLAuthenticationEnabled(true);
connConfig.setReconnectionAllowed(true);
XMPPConnection connection = new XMPPConnection(connConfig);

但每次我关闭再打开Wifi时,就会出现这个错误:

10-01 21:43:26.942: W/System.err(13695): javax.net.ssl.SSLException: Write error: ssl=0x5a4ad348: I/O error during system call, Broken pipe
10-01 21:43:27.002: W/System.err(13695):    at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native Method)
10-01 21:43:27.012: W/System.err(13695):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:693)
10-01 21:43:27.012: W/System.err(13695):    at java.io.OutputStreamWriter.flushBytes(OutputStreamWriter.java:167)
10-01 21:43:27.012: W/System.err(13695):    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:158)
10-01 21:43:27.012: W/System.err(13695):    at java.io.BufferedWriter.flush(BufferedWriter.java:124)
10-01 21:43:27.012: W/System.err(13695):    at org.jivesoftware.smack.PacketWriter.writePackets(PacketWriter.java:210)
10-01 21:43:27.012: W/System.err(13695):    at org.jivesoftware.smack.PacketWriter.access$000(PacketWriter.java:42)
10-01 21:43:27.012: W/System.err(13695):    at org.jivesoftware.smack.PacketWriter$1.run(PacketWriter.java:78)
10-01 21:43:27.092: W/System.err(13695): javax.net.ssl.SSLException: Read error: ssl=0x5a4ad348: I/O error during system call, Connection timed out
10-01 21:43:27.092: W/System.err(13695):    at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method)
10-01 21:43:27.092: W/System.err(13695):    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:651)
10-01 21:43:27.092: W/System.err(13695):    at java.io.InputStreamReader.read(InputStreamReader.java:244)
10-01 21:43:27.092: W/System.err(13695):    at java.io.BufferedReader.read(BufferedReader.java:310)
10-01 21:43:27.092: W/System.err(13695):    at org.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1496)
10-01 21:43:27.092: W/System.err(13695):    at org.kxml2.io.KXmlParser.peekType(KXmlParser.java:979)
10-01 21:43:27.092: W/System.err(13695):    at org.kxml2.io.KXmlParser.next(KXmlParser.java:346)
10-01 21:43:27.092: W/System.err(13695):    at org.kxml2.io.KXmlParser.next(KXmlParser.java:310)
10-01 21:43:27.092: W/System.err(13695):    at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:326)
10-01 21:43:27.092: W/System.err(13695):    at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:44)
10-01 21:43:27.092: W/System.err(13695):    at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:71)

有谁能解决这个错误,请帮我!


1
请分享您正在使用的aSmack库的版本。我正在使用asmack-android-18-0.8.9beta4.jar,并使用您上面提供的代码片段,当我在我使用的Nexus3手机上关闭和打开wifi时,我没有看到您遇到的错误。 - Gene Myers
实际上我不再使用 asmack 库了 :). 无论如何,非常感谢! - duong_dajgja
我很好奇,你现在在用什么? - Gene Myers
我希望我的服务器能够主动向客户端(Android)发送一些消息,因此我考虑使用GCM或XMPP。我尝试了两种方法,然后比较它们的延迟。我发现在大多数情况下,XMPP的延迟更小,但GCM的延迟也是可以接受的(至少在我的应用程序中)。所以我决定使用GCM而不是XMPP :) - duong_dajgja
4个回答

10

使用最新的 Smack API - 我正在使用 4.1.0 版本。

然后按以下方式设置重新连接:

ReconnectionManager manager = ReconnectionManager.getInstanceFor(connection);
manager.enableAutomaticReconnection();

此处所述,它会自动重新连接。


你知道当你已经连接时是否必须执行它吗?如果在尝试连接时没有互联网连接,您是否需要尝试在没有重新连接管理器的情况下连接,还是它会自动执行? - Kasas

0

在开始设置一切时,请调用

ReconnectionManager.setEnabledPerDefault(true);

此后创建的连接将自动重新连接。


0

Asmack支持重新连接,唯一的问题是您正在使用SASL连接,因此在关闭Wi-Fi后尝试再次使用相同的连接会出现问题。请尝试将SASL设置为false。

connConfig.setSASLAuthenticationEnabled(false);

必须手动断开连接

connection.disconnect();

-1

不要使用ASMACK中实现的重新连接机制。

请使用:

    connConfig.setReconnectionAllowed(false);

而不是这样,你应该创建一个BroadcastReceiver来监听ConnectivityManager.CONNECTIVITY_ACTION。 当连接到WIFI或其他网络时,你将在你的BroadcastReceiver中收到回调onReceive


这种方式不好。你可以通过以下情况进行检查:你的智能手机连接到一个AP,如果这个AP失去了互联网连接(假设你从AP中拔掉了有线电缆),在这种情况下,你的智能手机将无法意识到互联网连接的变化。 - duong_dajgja
@duong_dajgja,你说得对,但是Asmack中的重新连接管理器存在一个错误。也许这个错误已经在最新版本中修复了。此外,如果重新连接管理器被修复,那么你应该结合两种技术,以便在没有活动网络时不尝试重新连接。 当你调用connection.connect()时会发生什么? - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接