Lossing messages due to connection loss through openfire - android

Turning off internet on mobile device directly causes problems in my chat application. Messages are not stored in openfire offline table as Openfire still shows me online on abrupt disconnection from the server. when a relogin attempt is made the messages that were sent in that period are lost.
I am working on a chat application,after login to openfire I am able to chat and other users can see me online but the problem is if one user losses the connection like WIFI off,In such situation Openfire is not showing my status as offline and it still shows Online which results in message packet loss.
Please provide me the solution I am unable to resolve it.
On a sidenote how whatsapp and other apps send messages. Do they use message storage strategy on server and acknowledgement or am I missing something here.

Both client and Server needs to acknowledge that messages were sent & delivered, say for instance you send a message to someone else, what you can do here is that you save this message on your server, from server this message will be sent to receiver and wait for an acknowledgement by the receiver that the message was delivered, once you get acknowledgement - delete the message from the server.
How whatsapp do it? I found this answer by Michael Donohue on Quora
Whatsapp works on store and forward, The WhatsApp client will store any message you send, and keep trying to send it to the WhatsApp servers. When a WhatsApp mobile app connects to the chat servers, the store-and-forward process occurs in both directions. The client sends any pending messages in it's mesage store to the server, while the server sends all the accumulated messages destined for that client to the client. This process is done on an acknowlegement basis. This means messages are sent repeatedly until the other side acknowledges receipt of the message. server drops messages once they are acknowledged - there is no long term storage. Whereas the client will update the UI to double-check status once the ack arrives, but will keep the message.

In android client using Smack framework, you must disable Stream Mananement just after creating XMPPTCPConnection and before run connection.login().
connection.setUseStreamManagement(false);
I had this problem and with this code was solved.

Related

How to persist offline messages and sent to the message queue once device becomes online in android?

I have followed the following tutorial and created the RabbitMQ android application.
RabbitMQ on Android
I have created both the publisher and subscriber modules and I can be able to send the messages to message queue in publisher and receive the messages from the message queue in the subscriber.
In the publisher module offline messages are sent to the message queue if the application is opened until the internet comes back. If the application is closed then the offline messages are not sent to the message queue.
I want to send the offline messages to the message queue even if the application is closed. I know we can able to store the offline messages in the local storage and sent to the message queue when the device becomes online. But I want this to be handled by the RabbitMQ Android SDK. Is is possible to handle this with RabbitMQ? If possible please give me some suggestions.

MQTT: detect if submission is completed

I have a problem with the following scenario:
I Send a document from the Server to a mobile Device. I also send a notification about a new document in the inbox at the same time.
Problem is: Depending on the Device's Connection speed, that submission can take a while, so the notification comes in before the document is in the app's inbox.
So I want to send the Notification after the submission is completed.
Question: Is there a way for me to check if the MQTT data transfer is completed without having to have the client send a confirmation?
With MQTT, it is not possible for a publisher to know that all subscribers have received the message unless the subscribers also publish an acknowledgement back on another topic.

Latter Delivery Ack. from GCM to App server?

I am using GCM for Chat App. If User is Offline(not Connected to App but internet is active) then i Send push notification to devices It receive perfectly.
But when Device is totally offline(neither connected to App and nor active internet) at that time GCM send me response like { id: XXXXXXXX,success: 3,failure: 2{message_id:xxxxx,ect:..}} on my App server.
two device are totally offline they don't have active internet connection..
when device will connect to internet GCM Send them message.
but how can my App server will Know that Message is delivered by GCM.
I Search a lot but can't get any satisfied answer.
I tried that on messageRecive at client device(Android device) i will send httpRequest to my App server but it not suitable for my app it makes App very slow.
So Question is how Can i know that my failure 2 message are delivered.
First of all, you do not need to update your app server in case of a downstream message after it is sent to GCM Server. As explained here, GCM server stores the message in case of an offline device and delivers it once the device is online.
(Now assuming that what you want is to handle network tasks on the client)
You can use GcmNetworkManager to batch network discovery and connectivity related tasks across the system through Play Services. Go through the documentation.
You can use GCM Statistics and Diagnostics from Google Play Developer Console, too. This gives you details of messages handled by a particular app (through Registration token) down to status of specific messages (through message IDs). More explanation here.
(However I am not too clear exactly what you want)
EDIT
but how can my App server will Know that Message is delivered by GCM.
Sorry, reading through again I realised this is the real question. Answer is pretty straight forward here.
.

Flowchart of messages in GCM using the upstream messaging

I am trying to understand the concept of gcm upstream messaging.
Well what I came to know till now after browsing for hours is this :
1)My client app sends upstream message to gcm server.2)GCM server then sends it to my 3rd party app server.3rd party app server responds to it my sending ACK to GCM server.3)Then GCM server echoes the message to the recipient device(recipient Id is included in the upstream message sent from the app).
I don't if its what actually happens.
Now that I am sure that in some step GCM server sends mesaage to my server, how actually GCM server
sends message to my app server. How does it come to know about my app server as there is nowhere where we put my server's address
I have searched the whole Internet but couldn't find anything about this.I have gone through several SO questions but I couldnot find my answer.
I want to know the entire series of steps what happens during this entire process. I am very confused.I want to know the entire concept and what's going on behind all this.
Any detailed explanation with all steps will be appreciated.
To inform I have read the Google docs.
You have much of the flow correct but I think another read of the Docs will clear things up.
Your application server must act as an XMPP client, and connect to CCS (GCM's XMPP server). Your server connecting to CCS is how GCM knows the "address" of your server.
Cleaning up the flow you suggested:
Your app server connects to GCM's CCS.
Your client app (android app) gets a registration token.
Your client app (android app) sends that token to your app server.
Your client app send upstream message to GCM.
GCM fwds that message to your application server.
Your application server send Ack to CCS.
Your application server handles the received message.
Note the above flow is a possible one, there are many others, also downstream messages are not part of the flow. Again refer to the docs for more details.

Protocol used for sending push notification in Android

I want to know which protocol is used to send push notification to android devices and which to send push notification requests to GCM.
Whether it is HTTP, HTTPS or some thing else?
The protocols of the communication between the 3rd party server and GCM server (HTTP or XMPP) were already mentioned in the other answers.
The protocol of the communication between the device and GCM server is not discussed in the GCM documentation, since you never have to access it directly as an Android application developer, and therefore you don't need to know about it.
However, here's a quote from a Google developer from the team that created GCM, which says a few things about the connection. From what he says, you can only know that it's a long-lived TCP connection.
GCM maintains a long-lived connection - and reconnects if it knows the
connection was broken. A router/AP/NAT is supposed to send a FIN or
RST to terminate the TCP connection - so GCM and servers will know the
connection is dead.
However a number of routers and mobile operators don't do this, and
then GCM needs to rely on the heartbeat, ~15 min on Wifi, more on
mobile.
(The quote is taken from an answer by that person)
There are two protocols http and xmpp which you can use to send message to GCM server.
Now its up to you what you want to use. If you want to broadcast message then u should go with http.
you can broadcast 1000 message in a single http request. And only one message through xmpp in a request...
Http can be used only for down streaming(3rd party app server -gcm-mob device)
But gcm won't support up streaming using http.
for that you should use xmpp.Xmpp can be used for both up streamlining and down streaming.
Implementaction of push notification can be very easy if you are going with http and that much more hard if you are going with xmpp.but Google has provided detail tutorial how to implement xmpp.
So please have a look On Google developer site.
Looking at #user3523641's answer and further conversation, I'll try to explain further:
The way of delivering messages is based on the protocol that you've chosen, either HTTP or XMPP (i.e., it's the same). The magic and basic way of working is leaving a socket opened between the GCM server and the user's device.
This way, when an user should receive a message, this opened socket will be used and send the message through itself. This also helps the GCM server knowing which devices are connected or not. So this way, if your third party server says a message should be sent to a user and the GCM server knows the user is not connected, it won't send it at that time, but will try once the connection is again established, so it won't waste connection attempts in vain. The default timeout is 4 weeks, however, it can be changed.
As per the official GCM documentation:
If the device is not connected to GCM, the message will be stored until a connection is established (again respecting the collapse key rules). When a connection is established, GCM will deliver all pending messages to the device, regardless of the delay_while_idle flag. If the device never gets connected again (for instance, if it was factory reset), the message will eventually time out and be discarded from GCM storage. The default timeout is 4 weeks, unless the time_to_live flag is set.
Finally, when GCM attempts to deliver a message to the device and the application was uninstalled, GCM will discard that message right away and invalidate the registration ID. Future attempts to send a message to that device will get a NotRegistered error. See How Unregistration Works for more information.
You can find more info here.
It uses both HTTP and XMPP
When the message is processed successfully, the HTTP response has a 200 status and the body contains more information about the status of the message (including possible errors). When the request is rejected, the HTTP response contains a non-200 status code (such as 400, 401, or 503).
iOS however, requires a dedicated TCP connection on a proprietary port, and GAE environment doesn't allow any external protocol except HTTP over port 80.
The message size limit is 1024 bytes.
Google limits the number of messages a sender sends in aggregate, and the number of messages a sender sends to a specific device
This is how these components interact:
Google-provided GCM Connection Servers take messages from a 3rd-party application server and send these messages to a GCM-enabled Android application (the "client app") running on a device. Currently Google provides connection servers for HTTP and XMPP.
The 3rd-Party Application Server is a component that you implement to work with your chosen GCM connection server(s). App servers send messages to a GCM connection server; the connection server enqueues and stores the message, and then sends it to the device when the device is online. For more information, see Implementing GCM Server.
The Client App is a GCM-enabled Android application running on a device. To receive GCM messages, this app must register with GCM and get a registration ID. If you are using the XMPP (CCS) connection server, the client app can send "upstream" messages back to the connection server. For more information on how to implement the client app, see Implementing GCM Client.
Check out this for more details -->
Google Cloud Messaging for Android (GCM)
Android Cloud to Device Messaging Framework
Cloud Messaging
Cloud to Device Messaging

Categories

Resources