Saving the time the user is logged on - javascript

In the application I am developing I have to store the time some particular users remain logged into the application, unfortunately, in web applications, there are several ways the user can log off.
User clicks log off.
User session expires.
User closes the window.
User types another site URL in the address bar.
The first one is quite easy because the application gets control of the logging off process. But in the other ones, it gets tricky.
What would you do to solve this problem?

On each page view, update your count. If they log out, then you've got an accurate measure. If they navigate away, or any other method, then the most that you're out is the length of time they were on one page.
If it were really really important to have an accurate measure, then perhaps an AJAX "heartbeat" every minute, but that's most likely overkill.

Well for #3 and #4 you can attach something to the window.onunload event that gets you the time for calcuations, but be careful that your code is fast enough that the page doesn't completely unload before your AJAX request can be sent.
As far as #2 goes, the "heartbeat" suggested by nickf is probably the best solution there.

Related

What is the most reliable event to listen for when window is closed

I am building an online game, and one feature involves being able to put up a game request on the site so that other users can see it, and maybe accept it. For this site, I want to remove the game request of a user when they close the page, by either navigating to another page on the site, closing it altogether, following a link, etc. so that other users who are still online don't respond to a dead request.
The issue is, I was planning on writing code to do that and put it in an event listener that listens for the closing of the page, but apparently, some of the events have issues with them, according to MDN:
Unload/beforeunload: This event apparently does not fire reliably on mobile, especially when the user opens another app without closing the browser, and closes the browser with the app manager afterward. I imagine this could lead to problems on the phone, but this is my default option for now.
Visibility: MDN's suggested alternative to unload, the change in visibility event would fire when a mobile user opens another app, but it also fires when they open another tab in the browser. This would mean they would have to sit there looking at the lobby page until someone accepted their game request, which is not ideal.
Disconnection: Another thing I was thinking about was listening to the disconnection event fired by a socket (I am using socket.io to manage user connections) but I imagine that a disconnection due to a bad network can also fire this event, even if it is momentary. A user would then have to remake their request; also not ideal.
These are my main 3 options for now, and my question is: Is there an event that fires when a page is closed that I can listen to, that works like unload but also accounts for mobile users' issues as mentioned above? Or maybe something like the visibility change, but does not fire when they go to another tab? Or something else entirely that sidesteps both of these issues.
Use window.onbeforeunload. This allows you to do a few actions before the window either refreshes or is closed. For instance, you could store something to localStorage or a cookie to store that something happened. The reason why this maybe hasn't been reliable is because your script has to be quick. You only have a certain amount of time before the page unloads. Here is an example of something you could do.
window.onbeforeunload = function() {
document.cookie = 'goodbye=true';
}
Then you could check for this cookie when the page loads. If your page is on mobile, the browser may do nothing when a cookie is set or something is set to localStorage because of privacy measure. This simply is how it is.
You could use a combination of the different options. Assuming you can reliably detect whether they are on mobile or not. If they are on mobile, use the visibility event. If they are on desktop, use the unload event.
Another option is on the visibility change you could send a "I might be disconnecting" message and then use a setTimeout() to send a follow up message 5 seconds later saying "never mind!" Then on the server side you could set a "disconnect timeout" that waits 10 seconds for the "never mind!" message. If it doesn't receive it within 10 seconds, then drop the user and assume they disconnected.
I would use beforeunload but also prepare for the unreliability. When it works, it removes the request like you describe. Then also make it up so when a user responds to the game request, it pings back to the original user. If the ping fails, say something like "oops they left." If the ping goes through, query the original user "you got a response. do you still want to play?"

Change ASP.NET session timeout programmatically

Here is a new requirement that I need help with. Our users request that 2 minutes before the session timeout, warn them. (i can use a global javascript to check on every page since once a page is loaded, the session reset and by default, another 20 minutes is extended). at the 18th minute, a javascript popup shows up, asking the user "You have two minutes left before being logged off. Do you want to extend the session"?
Up to here, all is fine. But then once they hit "Extend it", then what? I don't want to refresh the page because the data they've already entered will be lost. Is Ajax needed? If so, what is the programmatic way to extend the current session? (not modifying web.config just to be clear)
Also, say they are talking to someone and did not see the javascript confirmation during the 2 minute. Is there anyway to "hold" the session, till the user decides to do something?
Thanks
I was recently working on a similar problem. With ASP.Net every call back to the sever resets the session timeout period. So a Ajax call is going to be your best bet.
As for holding the session, are you actually storing anything in the Session object that needs to be maintained? Or when you say session do you mean the period that the user is authenticated for? If it is truly Session and you are not storing data then it shouldn't matter id it expires. You may want to take a look ar the below link.
Forms authentication timeout vs sessionState timeout

Detecting Browser Close or Tab Close without Impacting other functionality

I want to invalidate the session when the user close the tab or browser in my GWT Application. I saw lot of threads Confirm Browser Exit in GWT but didn't get the solution which i am looking for. This should not fire when user refresh the browser(it shouldn't invalidate the session) and even it should not fire when user navigate to other screen or download any file.Any Idea?
There is no way to tell the difference between closing a window or navigating away in various ways. You may be able to get around refreshing a page issue by creating a timer on the server side to see if a user requests your page again within a certain period of time, but it's not clear what benefits you get.
From a user experience view, you should offer a Sign Out (Log out) button or something similar, so a user can clearly indicate an intent to leave your app. Also, you can set an inactive timeout on your session, to invalidate session after a period of inactivity.

Onunload, onbeforeunload - guidance requested

I have a web server that generates questions for students of a particular subject. The web server needs to keep track of how much time each student has spent on a particular set of questions.
The web pages have a "Finished" button, which, when pressed, causes statistics to be sent to server.
However, I also want the web browser to send statistics if the student navigates away from the page or closes the browser window without pressing "Finished".
For this purpose, I have planned to have "onunload" or "onbeforeunload" send an Ajax request to the server with the relevant information. But apparently different browsers do not fully support these events, and also there are restrictions on what can be done in the event handlers. And, of course, I don't want the browse to freeze if the communication with the server fails.
So, I need some advice on the best way to do this.
If I wanted to be sure to handle all the "special events" I would send tick 'requests' from the webpage to the server. Granularity depends on the tracking requirements, the load, and whether it is an intranet or internet application; can be some seconds or even a minute. So you are tracking the time spent on the page even if the browser/os/network crashes.
The best way to implement is, is to use period updates. This will pretty much guarantee you have some relevant data when the user disconnects in any way.
An implementation is pretty trivial, all tough you might have to refactor some of your logic to send out period updates instead of everything at once.
function sendStatistics()
{
// ajax and what not
}
setInterval(function(){
sendStatistics();
}, 1000);
An other way to make it work is to make your ajax call in beforeunload and make it synchronous. This will freeze the browser for duration of the call, and will also only work when navigating away or closing the browser, i don't recommend this.

Save HTML5 video currentTime before user leaves or closes page

I would like to save the position of HTML5 video's currentTime to the database when user leaves a web page. It seems like window.onbeforeunload is not a reliable way to do it (not to mention it gives an undesirable popup window!). Is there a better way to do this?
I can't think of anything other than saving the position to the server periodically. But that seems wasteful resource/bandwidth wise. Netflix seems to do a good job at remembering your last viewed position. How would they be able to achieve that reliably? Low-level server-side C/C++ code maybe?
There are various ways to save such things:
Locally (for the same domain)
beforeunload
This gives you the possibility to cancel the unload event if you desire. However, the popup is optional.
unload
This event can't be cancelled but you still have full access to all nodes and JavaScript variables. So you can do final cleanup/save then if canceling is not wanted. You can use whichever saving method you like, e.g. document.cookie or window.localStorage.
window.onunload = function () {
window.localstorage[myVideo.currentTime] = document.getElementById("myVid").currentTime;
}
If you can handle the fact that you can only process cookies and localStorage when the user comes back to your site. I think this approach would be perfect. You simply save the current time and on the users next visit you'll get the updated information.
On the Backend
If you really need to save that information to your backend you can try some other things.
DB polling
Depending on you accuracy needs you could send an ajax request every 10 - 20 seconds to update the playback time. If you just include the video id and current time, the request is so small it shouldn't have an effect on performance. However keep in mind that if you have lots of domain cookies it might increase the size of requests tremendously and your 500 byte payload might come with a 5kB header.

Categories