在Android上丢失的XMPP消息,同时切换数据连接(例如:打开Wifi, GSM Wifi开关)

时间:2022-11-08 19:52:33

I'm developing a chat application in android. Using XMPP server. PHP server has been migrated to ejabber.

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

My notification works properly in all scenarios. But in one case I am losing the XMPP messages. In fact I am not getting notifications.

我的通知在所有情况下都能正常工作。但在一种情况下,我丢失了XMPP消息。事实上,我没有收到通知。

In detail, I am turning off the WiFi or data connection. and after turning off WiFi or data connection any notification sent to me that is not getting. after when I turn ON the WiFi or data connection, I am not able to get the messages which were sent to me.

具体来说,我关闭了WiFi或数据连接。在关闭WiFi或数据连接后,发送给我的任何通知都没有收到。当我打开WiFi或数据连接后,我无法得到发送给我的信息。

I have implemented service in background. that makes xmpp connection always live.

我已经在后台实现了服务。这使得xmpp连接始终存在。

I getting this error while i turn OFF the WiFi connection.

当我关闭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 个解决方案

#1


4  

So to install mod_archive I need to do this, the typical: Write following line in cmd. (For cent Os)

因此,要安装mod_archive,我需要这样做,典型的:在cmd中写如下行。(分操作系统)

Login as root Create new directory:

登录作为根创建新目录:

mkdir ejabberd_archive_plugin
cd ejabberd_archive_plugin

now get the latest ejabberd modules using following command

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

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

Now go to ebin directory using following cmd and get the list of all *.beam files for ejabberd archive plugins.

现在使用以下cmd进入ebin目录并获得所有*的列表。用于ejabberd档案插件的波束文件。

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

Using following cmd you will get all ejabberd *.beam files list when ejabberd setup and configure.

使用下列cmd,你将得到所有的ejabberd *。当ejabberd设置和配置时,梁文件列表。

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

Now copy all *.beam (archive plugins) files to ejabberd ebin directory using following cmd

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

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

Now go to following URL and copy all sql table queries and run in phpmyadmin (ejabberd database)

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

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

Now configure ejjaberd.cfg using following cmd

现在配置ejjaberd。cfg cmd后使用

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}]},

Now restart the ejabberd service.

现在重新启动ejabberd服务。

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

#2


3  

You need "Stream Management" XEP-198 enabled connections to achieve this. Georg wrote a good blog entry about that topic: http://op-co.de/blog/posts/XEP-0198/ Basically it allows for stanza acknowledgement and stream resumption, which is exaclty what you want to do in case of e.g a Wifi <-> GSM switch.

您需要“流管理”XEP-198启用连接来实现这一点。Georg写了一篇关于这个主题的很好的博客文章:http://op-co.de/blog/posts/XEP-0198/基本上它允许stanza确认和流恢复,这正是你想要做的,以e为例。g a Wifi <-> GSM开关。

I conclude from the stacktrace that you are using aSmack (which is Smack ported to Android). There is a open feature request to implement Stream Management in Smack: SMACK-333. In fact, i've recently started working on the implementation, but can't name an ETA.

我从stacktrace中得出结论,您正在使用aSmack(这是Smack移植到Android上)。在Smack: Smack -333中有一个实现流管理的开放特性请求。事实上,我最近开始研究实现,但是不能命名一个ETA。

#3


3  

You have to create the separate web service for that. so thus why we can handle the history of the sent message. we can manage the offline message.

您必须为其创建单独的web服务。因此,为什么我们可以处理发送消息的历史。我们可以管理脱机消息。

XEP-198 is the only solution. make plugin for your server and make that easy to manage the remain message that is lose. there may be other solution but AFAIK, this would be the solution.

XEP-198是唯一的解。为您的服务器制作插件,并使其易于管理丢失的保留消息。也许有其他的解决办法,但AFAIK,这将是解决方案。

#4


1  

you can modify archive plugin to save message ids in it.

您可以修改存档插件,以保存其中的消息id。

When user comes online call a web service with last message id received. server can get all the later messages saved on the server. I created it i the same way and working perfectly well.

当用户联机时,调用带有最后一个消息id的web服务。服务器可以得到保存在服务器上的所有后续消息。我用同样的方法创造了它,而且工作的很好。

#5


-1  

You should relogin after reconnecting to the internet everytime. But, keep in mind that if you relogin with same resource and same user even it is online then server will throw stream error (replaced by new connection) which will make you offline & you won't receive any message. For this, disconnect yourself properly first before relogin. Try searching on mod Amp module.

你应该在每次上网后重新登录。但是,请记住,如果您重新登录的资源和用户是相同的,那么服务器将会抛出流错误(由新连接代替),这将使您脱机&您将不会收到任何消息。为此,在重新登录之前先正确地断开连接。尝试搜索mod Amp模块。

#1


4  

So to install mod_archive I need to do this, the typical: Write following line in cmd. (For cent Os)

因此,要安装mod_archive,我需要这样做,典型的:在cmd中写如下行。(分操作系统)

Login as root Create new directory:

登录作为根创建新目录:

mkdir ejabberd_archive_plugin
cd ejabberd_archive_plugin

now get the latest ejabberd modules using following command

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

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

Now go to ebin directory using following cmd and get the list of all *.beam files for ejabberd archive plugins.

现在使用以下cmd进入ebin目录并获得所有*的列表。用于ejabberd档案插件的波束文件。

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

Using following cmd you will get all ejabberd *.beam files list when ejabberd setup and configure.

使用下列cmd,你将得到所有的ejabberd *。当ejabberd设置和配置时,梁文件列表。

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

Now copy all *.beam (archive plugins) files to ejabberd ebin directory using following cmd

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

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

Now go to following URL and copy all sql table queries and run in phpmyadmin (ejabberd database)

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

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

Now configure ejjaberd.cfg using following cmd

现在配置ejjaberd。cfg cmd后使用

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}]},

Now restart the ejabberd service.

现在重新启动ejabberd服务。

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

#2


3  

You need "Stream Management" XEP-198 enabled connections to achieve this. Georg wrote a good blog entry about that topic: http://op-co.de/blog/posts/XEP-0198/ Basically it allows for stanza acknowledgement and stream resumption, which is exaclty what you want to do in case of e.g a Wifi <-> GSM switch.

您需要“流管理”XEP-198启用连接来实现这一点。Georg写了一篇关于这个主题的很好的博客文章:http://op-co.de/blog/posts/XEP-0198/基本上它允许stanza确认和流恢复,这正是你想要做的,以e为例。g a Wifi <-> GSM开关。

I conclude from the stacktrace that you are using aSmack (which is Smack ported to Android). There is a open feature request to implement Stream Management in Smack: SMACK-333. In fact, i've recently started working on the implementation, but can't name an ETA.

我从stacktrace中得出结论,您正在使用aSmack(这是Smack移植到Android上)。在Smack: Smack -333中有一个实现流管理的开放特性请求。事实上,我最近开始研究实现,但是不能命名一个ETA。

#3


3  

You have to create the separate web service for that. so thus why we can handle the history of the sent message. we can manage the offline message.

您必须为其创建单独的web服务。因此,为什么我们可以处理发送消息的历史。我们可以管理脱机消息。

XEP-198 is the only solution. make plugin for your server and make that easy to manage the remain message that is lose. there may be other solution but AFAIK, this would be the solution.

XEP-198是唯一的解。为您的服务器制作插件,并使其易于管理丢失的保留消息。也许有其他的解决办法,但AFAIK,这将是解决方案。

#4


1  

you can modify archive plugin to save message ids in it.

您可以修改存档插件,以保存其中的消息id。

When user comes online call a web service with last message id received. server can get all the later messages saved on the server. I created it i the same way and working perfectly well.

当用户联机时,调用带有最后一个消息id的web服务。服务器可以得到保存在服务器上的所有后续消息。我用同样的方法创造了它,而且工作的很好。

#5


-1  

You should relogin after reconnecting to the internet everytime. But, keep in mind that if you relogin with same resource and same user even it is online then server will throw stream error (replaced by new connection) which will make you offline & you won't receive any message. For this, disconnect yourself properly first before relogin. Try searching on mod Amp module.

你应该在每次上网后重新登录。但是,请记住,如果您重新登录的资源和用户是相同的,那么服务器将会抛出流错误(由新连接代替),这将使您脱机&您将不会收到任何消息。为此,在重新登录之前先正确地断开连接。尝试搜索mod Amp模块。