在切换数据连接时,在Android上丢失XMPP消息(例如,转换Wifi,GSM< - > Wifi切换)

时间:2014-07-10 10:51:14

标签: android xmpp smack asmack

我在android中开发了一个聊天应用程序。使用XMPP服务器。 PHP服务器已迁移到ejabber。

我的通知在所有情况下都能正常运行。但在一个案例中,我正在丢失XMPP消息。事实上,我没有收到通知。

详细说明,我正在关闭WiFi或数据连接。关闭WiFi或数据连接后,发送给我的任何通知都没有收到。在我打开WiFi或数据连接后,我无法收到发送给我的消息。

我在后台实施了服务。这使得xmpp连接永远存在。

我在关闭WiFi连接时出现此错误。

java.net.SocketException: sendto failed: EPIPE (Broken pipe)
java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
   at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
   at libcore.io.IoBridge.sendto(IoBridge.java:475)
   at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508)
   at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
   at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270)
   at java.io.OutputStreamWriter.flushBytes(OutputStreamWriter.java:167)
   at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:158)
   at java.io.BufferedWriter.flush(BufferedWriter.java:124)
   at org.jivesoftware.smack.PacketWriter.writePackets(PacketWriter.java:286)
   at org.jivesoftware.smack.PacketWriter.access$12(PacketWriter.java:270)
   at org.jivesoftware.smack.PacketWriter$1.run(PacketWriter.java:137)
Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
   at libcore.io.Posix.sendtoBytes(Native Method)
   at libcore.io.Posix.sendto(Posix.java:146)
   at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
   at libcore.io.IoBridge.sendto(IoBridge.java:473)
   ... 9 more
   at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552)
   at libcore.io.IoBridge.recvfrom(IoBridge.java:516)
   at java.net.PlainSocketImpl.read(PlainSocketImpl.java:489)
   at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
   at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:241)
   at java.io.InputStreamReader.read(InputStreamReader.java:244)
   at java.io.BufferedReader.read(BufferedReader.java:310)
   at org.jivesoftware.smack.XMPPConnection$AliveReader.read(XMPPConnection.java:1122)
   at org.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1496)
   at org.kxml2.io.KXmlParser.peekType(KXmlParser.java:979)
   at org.kxml2.io.KXmlParser.next(KXmlParser.java:346)
   at org.kxml2.io.KXmlParser.next(KXmlParser.java:310)
   at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:321)
   at org.jivesoftware.smack.PacketReader.access$1(PacketReader.java:216)
   at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70)
Caused by: libcore.io.ErrnoException: recvfrom failed: ETIMEDOUT (Connection timed out)
   at libcore.io.Posix.recvfromBytes(Native Method)
   at libcore.io.Posix.recvfrom(Posix.java:131)
   at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
   at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
   ... 13 more

5 个答案:

答案 0 :(得分:4)

所以要安装mod_archive我需要这样做,典型的: 在cmd中写下面的行。 (分为Os)

以root身份登录 创建新目录:

mkdir ejabberd_archive_plugin
cd ejabberd_archive_plugin

现在使用以下命令获取最新的ejabberd模块

yum https://svn.process-one.net/ejabberd-modules
cd ejabberd-modules/mod_archive/trunk
./build.sh

现在使用以下cmd转到ebin目录,获取ejabberd存档插件的所有* .beam文件列表。

root@ns1 [/ejabberd_archive_plugin/ejabberd-modules/mod_archive/trunk/ebin]# ls –l

使用以下cmd,您将在ejabberd设置和配置时获得所有ejabberd * .beam文件列表。

root@ns1 [/usr/lib64/ejabberd/ebin]# ls -l

现在使用以下cmd将所有* .beam(存档插件)文件复制到ejabberd ebin目录

root@ns1 [/]# cp /ejabberd_archive_plugin/ejabberd-modules/mod_archive/trunk/ebin   /usr/lib64/ejabberd/ebin

现在转到以下URL并复制所有sql表查询并在phpmyadmin(ejabberd数据库)中运行

https://svn.process-one.net/ejabberd-modules/mod_archive/trunk/src/mod_archive_odbc_mysql.sql

现在使用以下cmd配置ejjaberd.cfg

root@ns1 [/etc/ejabberd]# vi ejabberd.cfg 
Add the following line into ejabberd.cfg file in modules configuration section
{mod_archive_odbc, [{database_type, "mysql"}, {default_auto_save, true}, {enforce_default_auto_save, true}]},

现在重启ejabberd服务。

root@ns1 [/etc/ejabberd]# sudo service ejabberd restart

答案 1 :(得分:3)

您需要 "Stream Management" XEP-198 启用连接才能实现此目的。 Georg写了一篇关于该主题的好博客文章:http://op-co.de/blog/posts/XEP-0198/ 基本上它允许节确认流恢复,这在例如Wifi< - >的情况下是您想要做的事情。 GSM开关。

我从堆栈跟踪中得出结论,你正在使用aSmack(这是Smack移植到Android)。在Smack中实施流管理有一个开放功能请求:SMACK-333。事实上,我最近开始着手实施,但无法命名ETA。

答案 2 :(得分:2)

您必须为此创建单独的Web服务。那么为什么我们可以处理已发送消息的历史记录。我们可以管理离线消息。

XEP-198是唯一的解决方案。为您的服务器制作插件,并轻松管理丢失的剩余消息。可能还有其他解决方案,但AFAIK,这将是解决方案。

答案 3 :(得分:1)

您可以修改存档插件以在其中保存消息ID。

当用户上线时,请拨打收到最后一条消息ID的Web服务。服务器可以获取服务器上保存的所有后续消息。我以同样的方式创造了它并且工作得很好。

答案 4 :(得分:-1)

每次重新连接到互联网后都应该重新登录。但是,请记住,如果您使用相同资源和相同用户重新登录,即使它处于联机状态,服务器也会抛出流错误(替换为新连接),这将使您脱机并且你不会收到任何消息。为此,请在重新登录之前先正确断开连接。尝试搜索 mod Amp 模块。