15

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
Flow
  • 23,572
  • 15
  • 99
  • 156
Alpan
  • 518
  • 1
  • 6
  • 20

5 Answers5

4

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
  • same issue with me in android but we have OPENFIRE XMPP server...Can you please provide any idea regarding this ? – Mark Nov 03 '14 at 09:40
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.

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.

Flow
  • 23,572
  • 15
  • 99
  • 156
  • Problem for me is that I set the offline messages policy to "Always Store" and thus XEP-0184 doesn't really help out to determine if a message is not getting delivered to its receiver. Providing this scenario: - I have 2 users chatting, call them A and B - A sends B a message while B's connection just got lost - The message got dropped and A is not notified - In this case A does not know that the message got dropped, it'll just assume that the message is delivered to the server, server will eventually deliver it to B - B lose the message forever – Alpan Jul 15 '14 at 10:33
  • i am using stanza like this while connection – Alpan Jul 15 '14 at 10:34
  • and for resume but not working proper. sending request working proper. but i m not getting lost notification please give me proper solution – Alpan Jul 15 '14 at 10:36
  • 1
    the same thing happens in one scenario. and it works. when i will turn off mobile then i will send message from other mobile. and restart that device all messages are received successfully.... – Alpan Jul 16 '14 at 11:32
  • same issue with me in android but we have OPENFIRE XMPP server...Can you please provide any idea regarding this ? – Mark Nov 03 '14 at 09:41
2

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.

Krunalsinh
  • 240
  • 1
  • 13
  • let me go with XEP-198... but have not get the perfect solution. – Alpan Jul 22 '14 at 06:21
  • after searching for this answer, i am not able to get the perfect answer. but as @Krunalsinh's answer, i finished my stuff making separate Web-service. i don't think that this solution going to work for further time. :-( – Rumit Patel Jul 22 '14 at 06:30
  • @Krunalsinh your answer is contradicting itself... At one place you are saying create web service and at one place you are saying implementXEP-198. web service will be called using http connection and if you implement XEP - 198 than that will be implemented via xmpp connecetion socket connection – Jaspreet Chhabra Jul 22 '14 at 17:22
  • @JaspreetSingh, i managed all this by creating Web-Services.and all is running good, but as i said, it's not perfect solution and slower too. :-( – Rumit Patel Jul 23 '14 at 05:28
  • Web service is the only solution for now because XEP-198 is not up – Jaspreet Chhabra Jul 23 '14 at 07:36
  • @Rumit Alpan can you manage all server code using latest XMPP ? – Zala Janaksinh Oct 01 '14 at 10:26
  • @Rumit means your all webservice is XMPP related? Using openfire smack library? Your application is now complete? – Zala Janaksinh Oct 01 '14 at 11:21
  • @ZalaJanaksinh, Web Services are on different way, We use XMPP in only chat part. we have migrated from ejabber! – Rumit Patel Oct 01 '14 at 11:25
  • @Rumit Means your web service part is steel in PHP!! I think you are using Pusup notification..? – Zala Janaksinh Oct 01 '14 at 11:26
  • @ZalaJanaksinh, our WS is in PHP. and we are also migration on ejabbered from PHP. – Rumit Patel Oct 01 '14 at 11:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62254/discussion-between-zala-janaksinh-and-rumit). – Zala Janaksinh Oct 01 '14 at 11:38
1

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.

Jaspreet Chhabra
  • 1,431
  • 15
  • 23
  • 1
    I understand what you are explain to me. but as par your explanation till i am not getting proper solution. can you please explain me in deep. i am using stanza like this while connection and for resume but not working proper.sending request working proper. but i m not getting lost notification. please give me proper solution. any help would be strongly appreciated. – Alpan Jul 15 '14 at 10:39
  • I am not able to understand the packet and for resume – Jaspreet Chhabra Jul 20 '14 at 11:30
  • 1
    You have to create the web service that gets the offline messages for you. You have to create a plug-in for it or you can modify the archive plugin. – Jaspreet Chhabra Jul 20 '14 at 11:32
  • 1
    XEP-198 is still not up for smack so this is the only solution – Jaspreet Chhabra Jul 20 '14 at 11:33
  • 1
    I can give you full code if you are using openfire but I have not worked with ejabber server. You have to follow following steps : 1. When internet is connected send server last message received message Id via http get call to archive plugin(archive plugin save all the messages.) 2. Server will reply all the messages received after that message Id and reply back – Jaspreet Chhabra Jul 22 '14 at 17:10
  • Hello @JaspreetSingh sir , after few R&D i am confusing about the socket connection. because the ejabber and openfire both are working same. Is it possible the any plug in available in ejabber for archive plugin...? – Alpan Jul 23 '14 at 05:30
  • Sorry never worked with ejabber I can give you code for archive plugin on openfire server with web service implementation, my email Id is cvofjaspreet@gmail.com – Jaspreet Chhabra Jul 23 '14 at 07:35
-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.

TechHelper
  • 822
  • 10
  • 24
  • @JaspreetChhabra I am using it but not reconnecting getting java.lang.NullPointerException: Attempt to get length of null array W/AbstractXMPPConnection: at org.jivesoftware.smack.util.stringencoder.Base64.encode(Base64.java:61) W/AbstractXMPPConnection: at org.jivesoftware.smack.util.stringencoder.Base64.encodeToString(Base64.java:43) W/AbstractXMPPConnection: at org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism.evaluateChallenge(SCRAMSHA1Mechanis – Rahul Matte Aug 14 '16 at 14:12