My main question is how to detect the application termination by the end user when it was in the background (Suspended) to be able to send logout request to the server ?
We already have a timeout interval in the server to kill the session, but assume that the interval is 5 minutes so this means that the session will be alive for 5 minutes after the user terminated the app and anyone can sniff on the data and reuse it.
Notes:
We use HTTPS connection and SSL Certificate Pining.
We also implemented a heartbeat web service to be called by client app every fixed interval to tell the server to keep the session alive for this interval, if this web service didn't call for specific session, the server will kill this session.
Once your app is suspended you don't get any further notice before you are terminated. There is no way to do what you want.
Plus, the user could suspend your app to do something else (like play a game) and then not go back to your app for DAYS.
If you want to log out when the user leaves your app, do it on the willBeSuspended message. Ask for more background time and send a logout right then and there.
Mohamed Amer,
Here is an approach used by Quickblox Server and I feel its pretty much solid though it involves a little overhead.
Once the client application (either iOS android) establishes the session with quickblox server, quickblox server expects the client application to send the presence information to server after a regular interval continuously.
Sending the presense information is pretty much simple. They have written a api which we keep hitting after a interval of 5 mins with session id that we have. They validate the session id and once found valid they will extend the expiration time for the user ascociated with that id for 5 mins more.
What they will do I believe is that,
Approach 1 : they maintain the last hit time and for all the subsequesnt request they check if the request time is within the the time frame of 5 min if yes simply process it. If the request comes after 5 min they will delete the session id for the user and respond saying you have timeout the session.
Approach 2 : Because they provide online and offline info as well they cant simply depend on the incoming request to delete the session id from server so they probably create a background thread which swipes over the db to find the entry with last hit time greater then 5 min and removes it from DB. and declares the user session expired.
Though this involves client apps continously hitting the server and increases the burden on the server for the app like chat application in which presense information is so vital this overhead is still fine i believe.
Hope I have provided you with some idea at least :)
Related
I'm creating a simple web app that can connect to a bluetooth device that I want to be able to use offline, so I use a service worker to store the app in the web cache. I know the cache only clears if there is no more space but what about the service worker?
I found that is lifespan is 24 hours. My question is how long can I use the web app without connecting to the internet? Is the cache the only problem or does the service worker "die" after x amount of time and I need to connect to the internet again?
No, it does not die. You can use it forever.
You're confusing two things. The 24 hour lifespan is actually an automatic update checking interval. In other words, when using a site frequently the browser will automatically check for updated Service Workers (specifically updated /serviceworker.js or wherever you store it). Your code can of course manually, programmatically check for SW updates more often. Usually apps check for new SWs every time they're launched. But the device may be offline for eg a month and that doesn't prevent the use of the app.
As a slightly open question: Can/how does one send a network request every 5 minutes from a minimised iOS app?
In our case, we want to make sure that a certain message written when offline is sent as soon as the user regains internet access, even if the app is minimised.
Attempts at a solution
Most people are thinking down the 'app posting it' line, which hits the 3 min limit as mentioned.
Is there anything around the server pinging the app (perhaps with a notification) to trigger the app to respond with the required information?
I have an iOS application where I POST transactions to an API each time a transaction is completed. Once I get a 200 response code from the server I update an attribute on the transaction:
newTransaction.Synced = true
Incase the network connection ever drops I also POST every transaction where Synced = false when Reachability detects a network connection.
In perfect network conditions this works wells. However when I enable the Network Link Conditioner on my iPad and set packet loss to say 40% I start to see duplicated transactions on my server. What I assumed was happening is that it was taking longer than 30 seconds (the client side timeout on the request) to send my request and get the response from the server due to the high packet loss.
To confirm this, I made my API Sleep for 40 seconds for each web request and disabled Network Link Conditioner. As expected, the iOS app never set the Synced attribute to true as it was timing out before it got the response. However the server still created the entity for each POST request that was generated each time the iOS app launched or got network connectivity.
What's the best way to handle this situation so that duplicates never occur? I did think of adding a GUID to the transaction and then coding the API not to re-add the transaction if the GUID already exists. However the flip side is the iOS app would still never know the transaction has successfully synced. Is there a better way to handle this? Perhaps a timeout on the request which the server also adheres to?
Your Idea of assigning the GUID to transaction is good, but you might need to maintain a table on client side (browser memory) which will hold a record of all the calls you made to server and never heard back.
When you set the lifetime attribute of
<sessionTokenRequirement lifetime="00:10" />
Does that mean the token will expire in 10 minutes if there is no activity (no POST OR GET,etc) I am wondering if the user makes a post or get does it reset it back to 10 minutes. What I want is for the user to be logged in as long as they are actively using the app which should hit the server every minute or so. If they they stop using the app, I automatically log them out, but what I don't want is if they use the app for 11 minutes their claims have been removed. Could someone point me in the right direction?
Is it like the session timeout which times out if the user remains idle? If not is there something like that? Or am I using it in the wrong way?
I need to keep the app to send a simple GET request ("ping") to the server every minute just for it to know that user is still online. I have no problem with it while the app is active and 10 minutes after it went background using "beginBackgroundTaskWithExpirationHandler".
But how can I keep request repeated all the time unless user terminates app manually?
That's not really how it works -- it's not a Windows or a Mac app that runs continually in the background.
What you probably want to do is use the background fetch process, whereby iOS will periodically run a particular method allowing you to do network operations while your app is in the background (or not running at all).
What this won't allow you to do is ping your server exactly once every minute. But actually that's a good thing. Consuming a users battery and data allowance like that is not very user-friendly.