I've always used GCM for push notifications in android apps, but for security constraint i'm obliged to avoid GCM and use local push server, i've found a lot of answers for this question but none of them is well structured, i hope to get a clear answer for step by step process to use some XMPP server and client libraries for this topic
You may not fully understand what is GCM and what GCM was designed for.
Traditionally, each desktop applications establish its own TCP connection to its own server, just like you can connect to your Openfire instance and send/receive messages when you want without any third-party services.
This approach have many issues in mobile environment:
mobile devices are resource limited: when you have many TCP connections open it will drain your battery fast
mobile devices are not have persistent network connection: you should care about cellular and/or wifi network changes (and it also have battery impact) and you should not lose any messages in these unstable environment.
To solve these problems, Apple, Google (and also their minor competitors) provide "notification services". They are consists of:
System-wide background application ("service") which keeps connection to Apple/Google "notifications" infrastructure servers.
API for developers, to "register" their applications both on server and client side: your server-side application send all events to Apple/Google, and you client app receive "pushes" from that system service, you no need to care about network outages and battery impacts - all issues are handled by OS manufacturer.
But when you are trying to "avoid GCM" you getting all things to be cared by you, plus:
Your "handmade" persistent network service will interfere with Google's one, and will at least double network and battery usage (or even more, just because your implementation will have errors/other corner cases which are already where solved by Apple/Google big engineering teams)
Your application will dramatically more complex, and you will have much more security issues (as security issues are now handled by you, too) and poor user experience (applications with "own" networking are often have bad UX design, prompting and boring end user with network error messages, for example).
So, to sum up:
Yes, technically, you can take smack library and connect to Openfire server. Basically it the same as GCM works.
No, in 99.9999% of cases you should not go this way. Unless you are a big company which develops competing mobile platform.
Related
Edit: I've noticed that StackExchange has prefaced this question with Android but it applies for both iOS and Android.
We have a client side iOS/Android application that we expect to run (in remote Australia) with very limited internet connectivity. However, the application can expect to have very good connectivity to its local network, which is not on the net.
I've been looking into ways of waking a phone up with a notification of some sort whenever an event happens on the local server.
From what I've researched:
Web push is no good as even the newer VAPID based protocol still wants to route some data through the browser vendor's notifications server.
iOS Apple Notifications essentially have the same requirements as Web Push.
A background task which periodically polls the server/wakes up a Websockets connection can work, but could end up with pretty long delays between polls.
SMS is an option, as although 3G is limited, basic phone connectivity is sometimes available.
Are there any other ways of being able to wake up a locked mobile device with a server-sent event that I haven't listed? Given the operational situation having App Store compliance is not necessarily a requirement.
Cheers
After doing a fair bit of research, the answer (as of early 2018) is a pretty solid no, at least for a cross platform usecase.
iOS requires that an external notification that can wake the device come from a recognised internet-based source (APNS, and maybe in future the standardised VAPID based Push), from the mobile interface if available, or from the device itself which is limited by background execution restrictions.
I need to maintain an open, two-way communication channel between an Android app and an external server. I know that I can use GCM for this, but for various reasons that don't pertain to Android, itself, I would like to use websockets, if at all possible.
Can anyone point me to a comparison of resource/battery usage stats when using GCM versus a java-based websockets client under Android?
Thanks in advance.
Since multiple applications use GCM which uses a single socket connection to the Google cloud, making your application use GCM for notifications should not affect battery life at all since it just uses an existing connection. On the other hand, what ever process you create using websockets, that battery usage will just be added on top of GCM.
Also, if you need to maintain your connection even when the application is not in the foreground it will be necessary to create your application as a foreground service. GCM handles this for you.
Update
A device that has no other applications using GCM is a very rare case since many essential applications like gmail use GCM. I do not have exact numbers of the battery usage of GCM. But the battery usage of C2DM (GCM's predecessor which uses the same underlying communication model) is mentioned in this video around 4 minutes in. I actually had a similar question about the battery usage of a persistent socket connection to an external server (Android persistent socket connection rules). Although it is not a websocket I would image the battery usage to be similar. But again since GCM is built in at a much lower level of the OS, I would image it to be more optimized than a custom solution.
Unless you have some company policy against using a third party server or some very specific specifications, I would recommend using GCM. I would also encourage watching the entire video about C2DM as well as this video for GCM.
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.
can anybody confirm what are the currently allowed methods for peer-to-peer communications within the Android framework? I need to transfer json strings and I'm currently using SMS which works ok but the problem is that the data also ends up as lots of text messages. I've read Reto Meier's first edition of Professional Android Application Development where he says that the data transfer options were not implemented due to security concerns.
Has this changed at all and how would you do peer-to-peer transfer of data?
Have you looked at Qualcomm's AllJoyn library? It is designed to work over Bluetooth or wifi, so may fit, though if you're connecting over 3G or wider range networks it won't work.
Given the variation and reliability of networks between two remote devices not on the same network, I'd question whether peer-to-peer is the best solution, and would venture to suggest considering using an application server in between, so you could then use Cloud to Device Messaging [deprecated] (perhaps in tandem with Google App Engine). i.e. to send a message the sender passes it to the server, and the server then passes it on to the recipient.
In theory all devices on the net have a unique IP address and can talk to each other, but it's rarely that simple as routers/firewalls are configured differently so you'd need to pay great attention to the ports you use, especially considering many inbound ports are blocked by default for security reasons.
You can simply use UDP/TCP sockets. In a separate thread you set up the server-side listener socket and that's it. Of course your application has to be started first (or should run in the background all the time). Here's an example:
http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/
If you also need peer discovery that will make the thing more difficult.
You should also take a look at peerdroid, an open source project available here. I've been looking in to peer communication options from the point of view of having a collection of federated devices (pre-paired, if you like, similar to Bluetooth pairing); this library looks like it may give you the foundation for what you are trying to do.
If you are on your own network (for example a home or office WiFi) then you should be able to query for other connected devices. If the network you are on is not under your control (the mobile network or a public wifi) then the network will have been configured to isolate each device from everything else. In this case you will have no choice but to put a server up to act as the man in the middle. That brings its own architectural compromises - every device has to regularly poll the server or keep a connection open - unless you use Google App Engine which supports push notifications over Google's own infrastructure.
Thanks for your answer ldx but I would need peer discovery as you indicated. Some further research appears to indicate XMPP as a suitable technology and there are now some services on offer, although these appear to be aimed at 'server' to client notifications. There is a good discussion here on XMPP and some more here although it would appear that there are still some issues to deal with such as polling v push, long-running open http connections and battery life. Xtify looks promising, especially their web service. I hope this provides suitable information to others looking at the topic of peer-to-peer data communication.
I recently learned about the ability of iPhone apps to receive nearly instantaneous notifications to apps notifications to apps.
This is provided in the form of push notifications, a bespoke protocol which keeps an always on data connection to the iPhone and messages binary packets to the app, which pops up alerts incredibly quickly, between 0.5 - 5 seconds from server app send to phone app response time. This is sent as data - rather than SMS - in very very small packets charged as part of the data plan not as incoming messages.
I would like to know if, using Android, there is either a similar facility, or whether it's possible to implement something close to this using Android APIs. To clarify, I define similar as:
Not an SMS message, but some data driven solution
As real time as is possible
Is scalable, i.e., as the server part of a mobile app, I could notify thousands of app instances in seconds
I appreciate the app could be pull based, HTTP request/response style, but ideally I don't want to be polling that heavily just to check for notification; besides which it's like drip draining the data plan.
Firebase Cloud Messaging FCM FAQ is the new version of GCM. It inherits GCM’s core infrastructure to deliver messages reliably on Android, iOS and Chrome. However they'll continue to support GCM because lot of developers are using GCM SDKs today to handle notifications, and client app upgrade takes time.
As of June 26, 2012, Google Cloud Messaging is the preferred way of sending messages to applications running on devices.
Previously (and now deprecated), the service was called Cloud To Device Messaging.
XMPP is a good solution. I have used it for a push enabled, realtime, Android application. XMPP is powerful, highly extensible and easy to integrate and use.
There are loads of free XMPP servers (though out of courtesy you shouldn't abuse them) and there are open source servers you can run on one of your own boxes. OpenFire is an excellent choice.
The library you want isn't Smack as noted above, it's aSmack. But note, this is a build environment - you will have to build the library.
This is a calculation I did on battery life impact of an XMPP solution:
The Android client must maintain a persistent TCP connection by waking up periodically
to send a heartbeat to the XMPP server.
This clearly imposes a cost in terms of power usage. An estimate of this cost is
provided below:
Using a 1400mAh battery (as supplied in the Nexus One and HTC Desire)
An idle device, connected to an 3G network, uses approximately 5mA
The wake-up, heartbeat, sleep cycle occurs every 5 minutes, takes three seconds
to complete and uses 300mA
The cost in battery usage per hour is therefore:
36 seconds 300mA = 3mAh sending heartbeat
3600 seconds 5mA = 5mAh at idle
4:95 + 3 = 7:95mAh combined
A 1400mAh battery lasts approximately 11.6 days at idle and 7.3 days when
running the application, which represents an approximate 37% reduction in
battery life.
However, a reduction in battery life of 37% represents the absolute worst case
in practice given that devices are rarely completely idle.
I recently started playing with MQTT http://mqtt.org for Android as a way of doing what you're asking for (i.e. not SMS but data driven, almost immediate message delivery, scalable, not polling, etc.)
I have a blog post with background information on this in case it's helpful http://dalelane.co.uk/blog/?p=938
(Note: MQTT is an IBM technology, and I should point out that I work for IBM.)
Have a look at the Xtify platform. Looks like this is what they are doing,
Google is depreciating C2DM, but in its place their introducing GCM (Google Cloud Messaging) I dont think theirs any quota and its free! It does require Android 2.2+ though! http://developer.android.com/guide/google/gcm/index.html
If you can depend on the Google libraries being there for you target market, then you may want to piggy back on GTalk functionality (registering a resource on the existing username - the intercepting it the messages as they come in with a BroadcastReceiver).
If not, and I expect you can't, then you're into bundling your own versions of XMPP. This is a pain, but may be made easier if XMPP is bundled separately as a standalone library.
You may also consider PubSubHubub, but I have no idea the network usage of it. I believe it is built atop of XMPP.
I have been looking into this and PubSubHubBub recommended by jamesh is not an option. PubSubHubBub is intended for server to server communications
"I'm behind a NAT. Can I subscribe to a Hub? The hub can't connect to me."
/Anonymous
No, PSHB is a server-to-server
protocol. If you're behind NAT, you're
not really a server. While we've
kicked around ideas for optional PSHB
extensions to do hanging gets ("long
polling") and/or messagebox polling
for such clients, it's not in the core
spec. The core spec is
server-to-server only.
/Brad Fitzpatrick, San Francisco, CA
Source: http://moderator.appspot.com/#15/e=43e1a&t=426ac&f=b0c2d (direct link not possible)
I've come to the conclusion that the simplest method is to use Comet HTTP push. This is both a simple and well understood solution but it can also be re-used for web applications.
There is a new open-source effort to develop a Java library for push notifications on Android, using the Meteor comet server as a backend. You can check it out at the Deacon Project Blog. We need developers, so please spread the word!
Google recently(18May2016) announced that Firebase is now it's unified platform for mobile developers including near real time push notifications.It is also multi-platform :
The company now offers all Firebase users free and unlimited
notifications with support for iOS, Android and the Web.
source
I cannot find where I read it at, but I believe gmail utilizes an open TCP connection to do the e-mail push.
As GTalk is gone from the SDK, it might be a good idea to make a 'standard' push messaging system. That way, only one service has to run, only one extra tcp connection needs to be open. Applications should talk to this service using Intents and should first request permission to send and receive notification from the service. The service should then notify the user a new application wants to send and receive messages. The user will then grant or deny permission, so he stays in control. The application will then register an action + category to the service, so the service knows how to deliver the pushed message.
Would the a good idea or not?
Why dont you go with the XMPP implementation. right now there are so many public servers available including gtalk, jabber, citadel etc. For Android there is one SDK is also available named as SMACK. This we cant say a push notification but using the XMPP you can keep a connection open between client and server which will allow a two way communication. Means Android client and server both can communicate to each other. At present this will fulfill the need of Push in android. I have implemented a sample code and it really works great
I have recently developed http://pushdroid.org its a single application that should be installed on the phone just like google has implemented it in 2.2 this works from 1.5 and is broadcasting via intent.
The problem with GCM is that there is a lot of configuration involved in the process:
You have to add a lot of boilerplate to you Android app
You need to configure an external server to comunicate with the GCM server
You will have to write tests
If you like simple things (like me) you should try UrbanAirship. It is (IMHO) the easiest way to use GCM in your app without doing a lot of configuration. It also gives you a pretty GUI to test that your GCM messages are being delivered correctly.
You can find the docs and getting started guide here
You can find a sample application here
Note: I am not afiliated with UrbanAirship in any way
https://github.com/Guti/Google-Cloud-Messaging--Titanium-/blob/master/src/com/google/android/gcm/GCMRegistrar.java
Its reaily good and working solution for push.
Please try it
They have their listeners which has to be used by you by using their library classes in your code. You need not to bother about pushing. You have to send the message to server server will push the message to the device. They use OAuth. Regarding Protocols, there are two methods using CCS and XMPP. CCS just uses XMPP as an authenticated transport layer, so you can use most XMPP libraries to manage the connection. To send notifications to device you can write code in android app to send as well as your server code. the message sending will be done only by your code. Rest will be taken care by Google Server in GCM case. You can check detail at this link
http://developer.android.com/google/gcm/server.html
Also, for security issues
google cloud messaging security https://groups.google.com/forum/#!topic/android-gcm/M-EevBitbhQ
In case your app is not running then also devices can recieve notification because you have to write code for broadcast listeners. In background it will be listening to server and whenever any message packet will be there it will recieve the message as notification. Android has service you need to not to bother about it. You have only to use those resources using the library class that makes your work easier and let them write if your app is not running then also it recieve notification. Obviously, there would be some listener whick make the app to recieve.Check "Recieve the message" section in this link
http://developer.android.com/google/gcm/client.html
It will acccept request from users also. For GCM it will do. Please check "Send a message"
http://developer.android.com/google/gcm/client.html