XMPP messages lost on Android while switching data

2019-02-03 06:30发布

问题:

I'm developing a chat application in android. Using XMPP server. PHP server has been migrated to 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.

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.

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

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

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

回答1:

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

Login as root Create new directory:

mkdir ejabberd_archive_plugin
cd ejabberd_archive_plugin

now get the latest ejabberd modules using following command

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.

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.

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

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

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)

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

Now configure ejjaberd.cfg using following 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.

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


回答2:

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.

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.



回答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.

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.



回答4:

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

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.



回答5:

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.