This maybe a silly question, but I need confirmation and I have no one else to ask.
I am trying to understand the implications of implementing my own push notification for android mobile devices. This requires a continuous TCP connection to a server, though most of the time it will be idle.
My assumption is that, even when idle, for the server to be able to push data to the client through the TCP connection, an active internet connection will always be required, and if the connection is disrupted (i.e. the user switches the connection off) this push will no longer be possible.
Is this assumption correct ?
I'd say yes, it's correct indeed. How would you communicate without a live internet connection?
Afaik, Android C2DM handles this by queueing up the push requests when the user does not have a live net connection and sending them down to the user when the connection gets back up. You could implement a similar behavior in your solution's server side.
Answer is YES
To understand the best way then any-other about C2DM, You just should go through this Google Project C2DM
They have provided complete documentation required to Understand the work and mechanism of C2DM and provided completed Examples too.
I have one another favourite tutorial for the same is : Vogella's
You just need to give a good time to read this thing and implement..
Happy Coding :)
You are right. C2DM maintains a open socket (with Market or Gmail app), which it uses to identify your device.
And ofcourse, you will need Wifi or a cellular network to receive the push notifications.
Related
I want to send notification from one android device (android tv without bluetooth, telephony) to another android device (phone/tablet). Both are on same wifi network. Through the notification, I want to launch an app or open a page in phone/tablet browser.
I went through GCM messaging and also saw some options where we can have a kind of http server on the phone running but could not understand implementation.
Can someone help with idea and if possible, some piece of code as well.
As I need it for demo, so even any hack solution is fine for me :-)
Thanks for any help or reading.
Your best bet as a hacky solution is to do simple Socket connection between two devices. Since they are on same Wifi, it will be simpler and won't have any firewall restrictions.
Avoid GCM, it requires setting up a GCM Server and then complex registration. It also makes your solution dependent upon Internet connectivity & Google ofcourse.
See an example here:
http://android-er.blogspot.in/2014/02/android-sercerclient-example-client.html
Basically one device such as TV can be a socket listener. The phone/tablet can connect to that socket and then you can initiate a notification on either device based on your requirements and data exchange.
I have already implemented a push notification system for the android. My system works as following: From my server I communicate through the Http protocol with the google servers. Then the google servers are sending the notification to the mobiles. So, I was wondering if there are any alternatives ways to implement this functionality. However, I want something which will be reliable.
P.S. I would like to hear opinions from people that they implement something similar.
Not sure why you're looking for something else, if you've already got it working through the Google servers, but a good system to send push notifications easily is Urban Airship.
I was working with some Chinese tablets that could not receive android push notifs (very annoying). I had to implement a Comet like system on android.
Basically, on the android device, I created a service which essentially polled a URL. But since polling is very battery intensive, I used a push technique called long-polling. I had the Android http client set a very long timeout. I then on the server side had the server hold the connection open also for a very long time. What would end up happening is that as soon as a message had to be passed, the connection would finish, and the android device would get the message immediately. This is just an additional method of "push" technology.
The only other option not discussed here is a persistant TCP/IP connection. This can be very dicey because Android could kill the service at will, and it can be somewhat battery intensive as well.
From my experience, GCM is the best method out there, and I wish there was something as good as it available for iOS Devices!
I'm trying to develop a turn base game over XMPP. ( The only solution I found for multiplatform game ). I can send messages without problems. If the other user isn't online, the server (OpenFire) save it for later deliver.
The problem cames when a device change the network ( change from 3g to WiFi, change 3g IP... ) or the device lost the network ( turn off 3g, wifi or lost connection ). The server thinks that the device is online and send the message but it ( obviusly ) never arrive, so packet is lost.
I know one solution. Implement ACK over my game protocol, but I don't like this idea to much. Do you have any other suggestion? I think this is a server problem. Do you know another server witch implements TCP or ACK?
Thank you!!
EDIT: I do that: Connect device to server. I turn down the 3G and WiFi connectivity to the device. Android and the server still thinking that the connection is alive.
http://issues.igniterealtime.org/browse/SMACK-331
PD: I ask to openfeint for they multiplayer api, but they didn't asnwer me...
Although BOSH will likely work in this case, another option is XEP-0198: Stream Management. This will allow you to have all of the performance of a fully-connected socket, along with quick reconnects, positive acking, and queuing while un-acked or disconnected in both directions.
Under some conditions TCP/IP is not reliable. This is why ACKs, message receipts, IQs or other extensions in XMPP can solve this problem.
I have done lots of mobile programming over the years, also often with Openfire. But I have not seen lost messages. So I assume that there is a problem in either the library you are using on Android, or the Openfire version you use.
Instead of using raw sockets you can also use BOSH:
http://xmpp.org/extensions/xep-0124.html
BOSH is based on WebRequests like Comet and works very well in environments where you switch or loose often the connection. It can keep the connection alive until your network is back and does not result in connection drops when one or more requests fail in a row.
I too came across this issue and been trying to figure out a proper way to get this resolved.
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
So I temporarily put in a work around for this... i store all those messages that are not delivered (i.e. haven't receive the message delivery receipt) into a queue, then periodically (say, 6 minutes - it's the time when those dead connections got wiped) check every message of the queue to see if the intended recipient is "Online" AND the receipt's still not received... If it's the case, then I mark that message as "Failed delivery"
This is quite a terrible way to fix it (please advise if you have a better way of doing it). I think the best thing to do is to have the server to do this: if message failed to deliver and the offline message policy is "Always Store", then we store it to "ofoffline" for delayed delivery.
This is an old one, but I was solving such an issue recently. It helped me when I set the XMPP resource (the last part of full JID) to something reasonable, when building connection. Otherwise it will be random generated on each reconnect - and that changes the full JID.
I am having issues with C2DM. Sometimes works perfectly, sometimes my messages simply do not get pushed. Is there reliable way to enforce this connection? To pull messages. I read somewhere that what google do is keep low bandwidth TCP connection to their server at all time. So I assume that
when switching between network types TCP connection falls down and Android tries to reestablish connection to C2DM servers. So that might fail on WiFi with restricted network. Is that wrong assumption?
I have noticed with WhatsApp that on WiFi sometimes I do not get messages. When I switch to 3G I usually get them at the moment of the switch. What tips from your experience with C2DM would you offer?
C2DM is not suitable for critical parts of your application, since Google currently does not offer an SLA or paid tiers that will guarantee you reliable service and throughput.
I've considered several alternatives myself: XMPP via asmack, Parse, Deacon, Urban Airship, and MQTT.
After some reading and experimenting I decided to go with MQTT. It is a very lightweight telemetry protocol invented at IBM that fits quite nicely in the Android push notifications scenario. I recommend you give it a try, here's a nice blog post to guide you: Using MQTT in Android mobile applications.
Hope this helps.
C2DM does not guarantee that your message will be delivered, and your application should not assume that in order to work correctly. Therefore, your C2DM message should never contain the data itself but, rather, a notification that there is data available. In other words, the loss of a C2DM message should never cause your application to lose data; it should, at most, cause it to take longer to notice that a certain piece of data is available on your server.
A typical app should connect to its server once in a while (a long while) to retrieve messages, even when using C2DM, to cover the case where C2DM messages might not be delivered.
Depending on network configuration, the device might not be able to receive C2DM messages; restrictive firewalls or other strange WiFi configs might do that.
With C2DM reliability is not a guarantee. So best to have a ACK
message or some way in which you (the sender) the realize the message was received successfully.
Also make it a point to override onRegister class properly because the device Reg ID keep on shuffling.
Lastly, if you are planning to send updates regularly, I'd prefer polling to C2DM just because of the amount of requirements to get it functioning while reliability and ultimate control is still not assured.
I've been struggling with the same problem myself. The behaviour you describe is accurate. I'm developing an app that uses c2dm mainly with Wifi connection, and I had to implement an AsyncTask to periodically (minute and a half) call WifiManager.reassociate() (turning wifi off and on again triggers the arrival of all pending notifications, that's what inspired this solution) so I can keep the notification arrival as accurate as possible. Not so sure about the correctness of this practice, though.
Have you tested it every 15 minute connection? I created a schedule task to send the message. I use NotifyMyAndroid to push it. C2DM sometime pushes the message about 10 mninutes after not instantly. But, sometimes you get it in around a second.
The best way you can do this is by testing. I have a mechanism in my app that when I enable debugging I receive a HTTP request from the client saying that they received the message.
I find that this number is about 80%. Fortunately that's enough for the scope of my application.
Wifi shouldn't interfere in the C2DM ability of receive messages. At least while the phone is active.
What happens is that android turns the wifi OFF after the phone is in standby for a while. The messages won't be available at that period of time, simply because there's no internet connection available. Right after the user wakes the phone up, they should receive the messages.
After a long time research pretty much "all the internet" for an answer, I've found it. As I posted before, I was struggling with the problem myself and found out it was not a C2DM problem, or even a implementation problem. It was simply a router or firewall misconfiguration. Android uses a persistent TCP connection with a heartbeat keep-alive mecanism to ensures that the connection stays up. Google uses the state of the connection to determine if your device is idle or not. But if your router has a protection policy that checks for "unused" connections and terminates them, that won't work. Android notifications should be delivered (close to) instantly. I've tested this in my school network and home network, with two diferrent behaviour.
To resume: be sure to check your network configurations.
Some APNs work better than others with C2DM. Google "gtalk apn", for example, to find forums about the impact of the APN on C2DM.
http://www.liveprofile.com/
I was wondering if anyone would be able to explain roughly how an application like LiveProfile is implemented?
How do the messages get pushed over the network from one device to another. How do they know the address of the device they wish to send it to? Is there a map of IPs and LiveProfile PINs?
Is it HTTP? Just the general technology used would be a great help in improving my understanding of this aspect of Android and mobile engineering.
I don't know about that specific app, but there are several possibilities out there.
One is Google Labs' C2DM: http://code.google.com/android/c2dm/
Also, check this post. It has a very detailed explanation: http://tokudu.com/2010/how-to-implement-push-notifications-for-android/
Here is another one with useful info: http://blog.boxedice.com/2010/10/07/android-push-notifications-tutorial/
As a co-founder of LiveProfile I can shed a bit more light on what we've done.
LiveProfile was released before C2DM was available. Infact the market was fragmented and many were still using Android v2.0 and below. For this reason we ended implementing our own push based solution.
Our solution is a persisted socket to our servers at all times. When a user sends a message to another user, it gets routed through our servers and we decide who it should go to. If the persisted socket is connected then we push the data to them. If the user is not currently connected, we store the data in an queue and the user will receive all the messages on connect.
Update: A good resource is a talk from Google I/O 2009 which goes into detail about the battery life, how network / CPU effects it, etc. http://www.youtube.com/watch?v=OUemfrKe65c