I want to develop an app that requires near real-time communication. For efficiency and feasibility , I found that these technologies are usually used :
GCM (google keeps a socket open for messaging, and the developer's server sends messages to google's server, which then 'pushes' that message to the device)
Persistent socket- A socket, connected to developer's server is connected forever. whenever there is anything to be pushed, the server pushes it to the device.
Long polling- usually an HTTP request, but the server waits for any new message. If there is something new arrives, the server responds.
I would like to know what the battery cost for a send-to-sync message. In this architecture, a persistent socket ( usually GCM) , tells the device to 'check' for anything new from the server, ONLY when there IS something new to be checked. Then the device just polls for the new content.
My app will not have more than a 2to3 (maximum case) messages delivered to the client. So, is it a feasible thing to do ?
Could anybody tell me the approximate 'cost' of one http request ?
Related
Hi I am developing android application in which I want show whether other person is online or not so that person can intiate the communication.I thought about few solution :
1) Implementing heartbeat mechanism, in which device will send ping request to server after fix interval of time.
2) Server will send push type ping to client and client will give response on that so that server will know that client is online.
First case causes battery and data issue, while second one causes delay in push which will affect the process.
Is there any better solution for this problem? Apart from these or improvise version of above one.
nilkash. Virtually any method for checking network connectivity will at the end result in sending periodical pings between device and the server. Even push type ping will actually do the same (but it saves battery because push notifications aggregate messages for all applications in-to a single connection to a google server). So the best solution is just a proper combination of optimizations and you have to choose them depending on your requests.
Server pushes are power efficient, mostly because they reuse the
same connection for all applications, but the delay can be huge,
something like 10 minutes.
You can subscribe to connectivity
events and send "online" message to server once you are online. (But
not once you are offline because you are... offline). This will give
you immediate online events.
Do not send pings from device when there is no connectivity. Your application should be absolutely idle so as not to use battery.
There is no easy way to find out
when client goes offline on server side. You have to trade
traffic/battery for time resolution. More often you send pings, the
better resolution is. But you can't change ping interval for pushes,
so if you need better resolution, then you need to use your own
connection. But you can send other useful data through that connection too.
If you keep a TCP connection, then your pings can be
very data efficient: TCP keep alive packets are just 60/54 bytes.
But then you have to keep open connections with all clients on the
server. This may be a problem if you have a lot of clients.
The best combination may be something like that: you always send online message from a client when it becomes online. You keep TCP connection while the application is in foreground. You use the same connection to transfer data to and from the application. When your application goes to background you fallback to power consuming push based pings and do them at 10 minutes basis.
I'm working on app the share tasks between users. By Google Cloud Messaging, I can notify the user target that he has a new task shared. The problem is : GCM does not offer a delivery guarantee. Would someone use an app like WhatsApp if he took minutes to deliver a message or not come to hand? That's my problem with GCM.
So I've got a solution : Use Socket!!!
Using Socket.oi and Node.js, my dream came become really works like magic !!!
But as nothing is free, keep a socket connection has a very high cost for the battery. Some people argue that the use of Sockets when there is no communication, nothing in or out, no cycles, so there is no consumption.
My friends, I've read a lot of text and do not know what approach should I follow. I ask your help. Soket.oi? WebSocket ???
How to maintain a connection to my server permante preserving the most of the battery?
I appreciate everyone's help!
You need to use mix of a socket connection and GCM. Both connection types do no guarantee delivery so you need to implement mechanism which checks consistency of messages history.
Simplified scenario could look like this:
a user launches your client
the client app registers at GCM and sends google id to your server.
the client app establishes socket connection
your server sends messages to a client through GCM and socket connection (if it is establish with particular connection)
each message has unique id, therefore the client could just ignore second identical message from Google of a socket connection
About not delivered messages:
When client connects to the server through socket connection it should receive response where history of messages should be put. It shouldn't be full history, it could be just last message (in case you develop chat app). Then a client just checks if he has notified user about last message or not. If not then your client makes request(http or through socket) to your server and receives undelivered messages.
Battery consumption:
Do not acquire wake lock to maintain socket connection! A device must go sleep. GCM will wake up handset.
Socket.io is good, and certainly useful in many real-time applications, but what happens when the app is terminated by the user? Or if the user restarts their phone? How would you receive notifications then?
For all purposes, GCM is good enough.
I am an android user and of course I use whatsapp, twitter for android, facebook and many other apps that notify me of events.
As a proogramer whats keeps me wondering is how fast notifications or whatsapp messages arrive.
My intuition tells me that is not possible for the whatsapp or twitter server to open a TCP connection with my cellphone by a given port to deliver a new message. If i am in wifi mode the router would block that connection.
And if my whatsapp client is pooling the server every second.... Poor server if it has 1000 clients making request every second.
What is the approach to face this issue?.
Is there some other protocol involved?.
Those apps use services that utilize "long polling" - primarily based on XMPP or some variation of XMPP (like jabber - http://www.jabber.org/). The client does not poll often. A quote for the Wiki page:
The original and "native" transport protocol for XMPP is Transmission
Control Protocol (TCP), using open-ended XML streams over long-lived
TCP connections.
It sends a message to the server that basically is a mechanism for the server to send a message back at any time (as long as the client is available). It's like sending a request to an HTTP server and the server "time-out" does not occur for a very long time (hours), so the client just waits. If the server receives a message destined for the client, it sends a "response" to that request. After the time out does occur, the client sends another request and waits.
GCM does the same thing - but does not require you to setup servers for all portions of the connection. It's easy to search for GCM, AWS, etc. to see examples.
Typically GCM should be used if you dont want to guarantee immediate delivery and it is okay for your app to miss out on certain messages.
This is because GCM tries to optimize by bundling several messages (even from other apps) into a single package. And it has a limited buffer to maintain the messages per device (in case the device is not reachable).
Here is just one way to do the job.
I have a question regarding a simple messaging application which I want to write.
Lets say we have 1000 clients. Now client A writes a message to client B.
Of course, client A sends the message to a server which distributes the messages. But the next step is unclear for me:
Does the server send the message to the specific device of client B? If so, how does it address explicitly this device and not send it to the other devices as well?
Or does client B continuously check for new messages on the server which are addressed to client B?
I am not sure if idea 1 is even possible, and what is the best way. But I just want to ask for how it is normally done.
Those are both valid ways to create a chat platform. The problem with option 2, which is generally referred to as a "polling" model (where the client "polls" the server for new messages on a regular basis) is scaleability. In your example alone if you have 1000 clients you would have 1000 requests to the server for new messages every interval. To give the appearance of real time messaging this interval needs to be pretty short (i.e. a few minutes at most). If you do the math you can see that the volume of requests can balloon very quickly.
The better approach is option 1. Using something like OpenFire and the Smack API what you're describing - the server sending messages to client B - is possible. You can read more about the APIs here. The idea is the same as push notifications. Client A sends a message to the server which then will "push" that message to Client B. This is scalable and eliminates the need for polling (which kills server resources and the phone' battery with constant HTTP requests).
I'm currently in the process of developing an app which has some very demanding needs.
The Project
An application which can communicate with a server is needed.
Small messages has to be send to the app which could display a notification or start an activity.
The Demands
Client needs to be sure that the phone is 'connected' at all times.
The client expects that the app can tell when it's no longer connected (or able to connect) to the server it tells the user.
Client needs to be able to send a message to individual devices
If the client needs to broadcast a message to the connected devices and to the individual devices.
My thougts (or problems)
Currently, the app is polling the server with a http request once a minute - if the app isn't able to connect to the server the user gets notified. The polling is able to tell which device is calling and telling it if it has a message for it.
But...
IMO this is a terrible design - it generates a lot of excess traffic, uses resources which probably wasn't necessary and it offers a lot of issues with connectivity (which I'm not sure I'll ever get past no matter which method is used).
I need your experience to select the right solution for my project.
I've been thinking of C2DM, but I'm not sure this could cover my needs?
Is polling for my only real solution?
Is there a third option I haven't thought about?
I stumbled upon a new service called Parse.com they seem to offer functionality for easy push-implementation for Android using their backend. It's commercial but they have a free plan too.
If you want to do your own implementation there seems to be a lot of articles about using MQTT which is designed for low-power devices. But I haven't seen any ready-to-use implementations of this yet.
I'd consider MQTT as a good solution, although it is what I'm most familiar with. Disclaimer - I write an Open Source MQTT broker. You could achieve what I think you want like this:
Have an MQTT broker running somewhere. The service on the phone connects to the broker and subscribe to a unique topic, e.g. device/23412364, where 23412364 is the per device unique id and referred to as <phone id> below. When your client wants to send a message to a specific phone, the message goes to device/<phone id>. If you want messages to go to all phones, then the phones could also subscribe to device/all for example.
If you make your subscriptions and messages have Quality of Service of 1 or 2 and set the "clean session" option for the clients to false, then messages will be queued up on the broker if the phone disconnects for whatever reason. QoS=1 means "at least once" and QoS=2 means "exactly once". When the phone reconnects, those messages will be delivered.
You could also have the phone send a message like "register <phone id>" to a fixed topic just after it connected (topic of "register" for example). A feature of MQTT that is very useful is the "Last Will and Testament". When you connect a client, you have the option of specifying a Will message and the topic that it should be delivered on, in the case that the client disconnects unexpectedly (ie. without telling the broker that it is going to disconnect). So you could set the will message to be "unregister <phone id>" and to be delivered to the same fixed topic as above ("register" in this example). You could then have another MQTT client at the server end sitting subscribed to "register". When a phone connects, it sends a "register <phone id>" message, when it gets disconnected the broker sends "unregister <phone id>". The MQTT client can therefore keep track of the connected clients at the server side.
At the phone end of things, you can get notified if the TCP connection goes down through normal network code.
Some relevant links:
Using MQTT in Android mobile applications: http://dalelane.co.uk/blog/?p=1599
Trivial MQTT Android project based on above: http://mosquitto.org/2011/11/android-mqtt-example-project/
MQTT Power Profiling: http://stephendnicholas.com/archives/219
MQTT features: http://mosquitto.org/man/mqtt-7.html
Facebook using MQTT: http://www.facebook.com/notes/facebook-engineering/building-facebook-messenger/10150259350998920