I have an application that sends data to a server with a post request. This request can fail, and if it does I want it to retry until it's finally sent, something similar to WhatsApp: if u send a message when u are offline it stays as pendant and when you go online again the message is sent.
Since I don't know how WhatsApp internally works I have some doubts in how to implement that. I thought two ways:
1- Setting an AbstractThreadedSyncAdapter to be executed every X time (like 30 seconds) that checks if there is data to send and, if there is, it sends it to the server.
2- When the user clicks to send some data, I create a thread that tries to send it and, if it fails, it sleeps some seconds and try again.
I really don't like any of these options. The first one is going to increase the battery usage since the application is going to perform operations every X seconds even if it isn't needed. The second one is going to use a lot of battery if the request fails a lot of times.
Is there any better way to do it? It'd be awesome if there was an easy way to detect if the phone has connection to internet.
Thanks!
In your scenario 2, you can set an alarm when the initial post fails to trigger a re-sent some time later. If the send succeeds, you cancel the alarm (or don't schedule another one).
For getting noticed when the device goes online you may look at this answer: https://stackoverflow.com/a/11084311/100957
Related
I Will describe my use case with figures attached and everything i can do to be clear so we may get up with a better idea ...
General idea:
Whatsapp chat application with firebase
Use case:
As we know one of the features of whatsapp is the last seen, when the user did (exited the app, log out, lost wifi connection, etc ..)
I tried to use:
onDisconnect, but onDisconnect gives bad result when losing wifi connection (because of the socket latency to be timed out)
the one I am using now, is every user updates its timestamp every 3 seconds (update document every 3 seconds), when the user loses connection,
he won't be able to update his timestamp, right? So, if another user wants to chat with this offline user, I can show him the user's last seen. Hope this
this is clear...
Developed using Flutter framework
Redux to manage app state
Firebase, cloud firestore
The code below is dispatching an action every three seconds, this dispatched action will update the last seen in firebase...
timer = Timer.periodic(Duration(seconds: 3), (Timer t) {
// store.dispatch(updateUserOnline());
});
As you can see in the figure below my data structure of how I am updating last seen for this user every 3 seconds ...
This implementation is very expensive to get satisfactory results for a last seen for a user, if we have million users and these million users are updating their
last seen every 3 seconds it will cost a lot $ per month, as we are doing a write operation, no?
So, my other solution is to implement a socket connection to my own server and let all the users listen to the onDisconnect socket event on my server instead of Firebase server, is this doable to avoid the huge cost of writing operations?
image attached: here
Firebase writes would indeed be a bit costlier since you would be sending in a lot of writes, which, apparently are just for the job of "last seen".
Instead, as you mentioned, having a socket connection with your own server will help reduce the number of queries you make. i.e. As soon as the socket disconnects from the server, you can send a write operation to Firebase. "Every 3 seconds vs Only when the user disconnects".
Plus (not something that you asked for), if you would be setting up a socket server of your own, then it shall help in the following scenarios as well:
Typing events (The indication we get when the other person is typing a message)
Quicker way to know if the person at the other end is online/offline (because of sockets)
I have an mobile application (iOS and Android) and I need send some notification from my server to these, then the mobile app need to make some tasks and when they finish, send a message from mobile to server to confirm. I have thought using Push Notification, but the problem is if the user disable this feature, the app will never receive this notification. Anyone know some direct communication server-app but keeping security?
You may try the long polling technique. But it will drain your battery very fast, so be careful. The main idea is that you set connectionTimeout to a very very long time (30 mins for example) and when not closing that connection until the server says there is something. After receiving an answer or timeout, just reopen it.
Another approach is to make some method like getJobStatus on the server, assign a unique id for your job and ask the server if it's complete every N minutes for example.
When trying to synchronise the client with the server, we usually need to combine both push and pull.
Something you can think of:
The server provides an API that allows the client to get the latest updates.
On the client side, when the app is active, use a timer to try fetching updates every N minutes.
When the app is in the background, use a background fetch to try fetching updates. In this case, the user doesn't care about if the task is done instantly, because his is not using it.
Call the getUpdates when the app becomes active from the background, to make sure handle the updates when the user starts to use it.
I have an application with list of data that I get from server with http request. Now I want to make a notification when new data is available and I assume that it can be achieved with service.
Is that a good practice? Is there any limitations for number of requests made from service?
What I want to achieve is something like gmail application. When I get a new email, notification is shown.
I want my app to be as up to date with data as possible, but I understand that making requests every 5 seconds might be too much.
I am open to all alternatives and various ideas how to do that.
Not sure if you really need to pull data every 5 seconds. Of course, it is too much. You have two options:
Use GCM as #duynt suggested in comment. Follow Try cloud messaging for Android if you've never used it. This way you don't need to worry managing your service locally but whenever there is a latest data available, you will get notification so you can place request to get that and update in notification.
GCM needs An application server that you must implement in your environment. This application server sends data to a client app via the chosen GCM connection server, using the appropriate XMPP or HTTP protocol. Take a quick look About GCM connection server.
For any reason if you would like to pull data from your local Android Service component, you can still do that. But 5 seconds frequency is really high. As majority of the times the device is in sleep mode, you have to wake up the device then send request to pull data. Waking up device every 5 seconds means a battery drain along with consuming data.
If you still want to proceed with local service option by increasing the frequency, make sure you follow How to use http in sleep mode and implement it that way otherwise it wont work in deep sleep mode.
You have to make a decision now.
I am writing the app that can chat with other. I saw some project : Parse, GCM,... It is exactly good. But I need to know how it work. Because want to use my own.
In my case, I saw when other send his chat, then it's almost display on my screen after 1-2 seconds. Then I think what happened:
My friend post his chat to server, and server send request to app with ID ( unique).
In my app, there have a service, which send request to this server each 1 second to get new chat, or notification. If found, display in my device.
Is my above ideal true? I am going to write about chat with client-server.
Give me reason why down vote.
Thanks :)
In my app, there have a service, which send request to this server each 1 second to get new chat, or notification. If found, display in my device.
Implement as you say lead to energy(own app services use)/IO(every net request each 1 second)/server(large amount request from clients, and most of request is useless because nobody chat in 24h) waste, and message may lost or can't get notification in time if the service is killed by system(or don't start).
However, your method will work if you find a way to keep your service always alive, and make well design for servers to support large amount requests from large multi clients.
For the better, you can use dynamic look-up algorithm that keep a long interval if there is no notification recently.
Recently google introduced push-to-device service, but it's only available 2.2 and up.
I need a similar system in my app, and I'm trying to get around limitations.
The issue is battery life. Since the user must be notified immediately about the changes on the server, I thought to implement a service that would live in the background (standard Android service) and query the server for updates.
Of course, querying the server, even each second, will cost a lot of bandwidth, as well as battery, so my question is this: does it make a difference if the server is holding the response for some period of time? (the idea behind Comet type ajax request)
Works like this:
Device sends request for data update
Server gets the request and goes in the loop for one minute, checking if there are updates on each iteration
If there are updates, server sends response back with updates
If not, service goes on to the next iteration.
After a minute, it finally sends the response that no data is yet available
After response (no matter whether empty or with data) Android fires another such request.
It will definitely cost less bandwidth, but will it consume less (or even more) battery?
Holding a TCP socket (and consequently waiting for an HTTP response) as you suggest is probably going to be your best option. What you've described is actually already implemented via HTTP continuation requests. Have a look at the Bayeux protocol for HTTP push notifications. Also, check out the Android implementation here. For what it's worth, that's definitely what I would use. I haven't done any sort of analysis of it, but this allows you to minimize the amount of data transmitted over the line (which is directly proportional to the power consumption) by allowing the connection to hang for as long as possible.
In short, the way Bayeux works is very similar to what you've suggested. The client opens a request and the server waits on it. If it has something to send, it sends it otherwise it simply waits. Eventually, the request will timeout. At that point, the client makes another request. What you attain is near instantaneous push to the client from the server without constant polling and duplication of information like HTTP headers, etc.
When the phone is actively using the networks, it's battery is used more. That is to say when it sends the request and when it receives the response. It will also be using battery just by listening for a response. However, will the phone download data, checking to see if there's a response? Or will the phone just be open to receiving it and the server will push the response out to the phone? That is mainly what it depends on. If the phone is just open to receiving the response but does not actually use the network while trying to download some response the whole time it's waiting, it should use less battery.
Additionally, the phone sending a query every minute instead of every second definitely uses less battery, as far as using the networks goes. However it depends on how you make the phone hold, if you tie it up with very complex logic to make it wait it may not help battery life. That's probably not the case, however, and I would say that in all likelihood this would work out for you.
In closing, it should help the battery but there are ways you could make it in which it would not. It wouldn't hurt to write the program and then just change some type of variable (for example WAIT_TIME to 1 second instead of 1 minute) and test battery usage though, would it?