tolgatanriverdi tolgatanriverdi - 21 days ago 5
iOS Question

Get Offline Messages From XMPP Without Becoming Online

We are using ejabberd server for our mobile chat application.
And we are using IOS XMPP-Framework for our IOS application ( https://github.com/robbiehanson/XMPPFramework)

But we have a problem on implementation that we couldn't find a solution.
We've implemented every aspect of XMPP messaging and all works good besides one thing:

While our application is on background, our ejabberd server sends us push notifications to inform us about offline messages. (Only sends notification for offline messages)

Then we've decided to implement the IOS background push notification functionality to get offline messages while the application is on background.

But the problem is we have to become online(send presence) in order to get offline messages.
But when we do that it creates 2 unwanted consequences:


  1. The party who sends the message saw our presence as Online (Even though we are in the background)

  2. Just because we are becoming online while the application is on background , our server cannot send push notification for other people's messages becuase we are online and server can only send notification for offline messages.



For solving that problem, only thing that I can think of is, if there is a way to retrieve offline messages from xmpp server without becoming online.
Does anyone know if Is there any way to do that with XMPP-Framework for ios

[EDIT]
Let me clarify the issue a little bit more:


Problems are more than just one:

Problem 1 - Push notification problem:

1.1 - Server check if the message is sending to an online or offline user. If the user is offline server sends push notification to inform user but if the user is online server doesnt send anything.
1.2 - When the application is in background and receive notification for offline messages, application become alive(still in background) and become online in order to get offline messages
1.3 - Because the client became online, server doesnt send the push notifications anymore but the application is still in background so the user cannot be informed about the message he/she received.


So In order to fix those problem I need to find a way to receive offline messages by not sending the online presence to server

Problem 2 - Message Receive Problem

2.1 - Server check if the message is sending to an online or offline user. If the user is offline server sends push notification to inform user but if the user is online server doesnt send anything.
2.2 - When the application is in background and receive notification for offline messages, application become alive(still in background) and become online in order to get offline messages
2.3 - When the application became online server sends all offline messages to client but doesnt send the total count of offline messages(At least I cannot get it with IOS XMPPFramework)
2.4 - So I dont know how much longer the client should stay alive in the background because I dont know the total count of offline messages, so after getting 2-3 messages I have to suspend the application in the background. But in that case there might be buggy situations such as XMPP Framework receive the offline message but I suspend the client application before writing it to database etc...


In order to find a solution to those problems:


  1. I need to find a way to get only 1 offline message when I want from server

  2. If possible I also need to get those offline messages without becoming online


Answer

Look into ejabberd_mod_offline_post

  1. First config the Room must be a Member-Only room, and add all users as members right after you created it, so that be able to get a total.
  2. Add above module into ejabberd modules.
  3. Implement a Callback Service to handle the callback post.

The idea is when User go offline:

  • In one-to-one case, offline_message_hook will be raised
  • In MUC case, muc_filter_message will be raised, and any one not Presence-Available is offline.

[Edited]:

I was using it on 16.06. And there was an error in the source code at lines:

...

Body = xml:get_path_s(Stanza, [{elem, list_to_binary("body")}, cdata]),

...

 Type = xml:get_tag_attr_s(list_to_binary("type"), Packet),

 Body = xml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]),

...

I fixed them by adding f to xml:, e.g. Body = fxml:get_path_s(Stanza, [{elem, list_to_binary("body")}, cdata]),

And for MUC, the offline users is in the 'Offline' field as this format, 'user1..user2..user3..', what you need to do it to split them out from the string.

Comments