I am working on a page where a user can lock records when he is working on them. While working on the records, a session (via RESTful API) locks records. Every 15 seconds, I am sending a "heartbeat" signal to my API to show that the session remains active.
I also have a "onBeforeUnload" function, which gives a warning when someone has made changes, but did not save them.
My problem is: While the beforeUnload dialog is up and running, it seems that te rest of my javascript code is not executing. This means that my heartbeat is not sending, and a background job will remove the session if the dialog is up for too long.
Is there any way to keep sending my heartbeat signal sending, while the beforeUnload dialog is active?
Related
I am working on implementing a "presence" feature on a website built on a classic asp (vbscript), SQL Server, javascript, IIS7 stack.
The existing authentication/log in system uses sessions, with a default 20 minute session timeout. The user data is stored in a SQL Server table. A cookie is also set when a user logs in, which enables tracking of registered users even when not logged in.
There is a column in the USERS table which holds the state e.g. "online" or "offline". The following is the logic I've come up with thus far:
Status is set to "online" when:
user logs in
a cookie is detected e.g. user returns but doesn't yet log in
Status set to "offline" when:
user logs out
user closes browser (use a javascript event to detect)
user navigates away from the site (not sure yet how best to detect this)
users session expires (handled in global.asa's Session_OnEnd subroutine)
Questions:
Am I overlooking anything in the logic presented above?
What is the best way (within js / classic asp) to detect items 2 and 3 above in the "when to set status to 'offline'" list
Thanks
With 2 and 3 there are js restrictions as to what you can do when js detects a potential leaving of the page. I think all you can do is to show a message before they leave. This means you wont be able to run any js as they are leaving.
Best way to detect when a user leaves a web page?
As Gary said probably the most effective way is to use some ajax to ping a script on the server to update a LastTimeOnline field in your db.
Another way is to use the Session_OnEnd but this may give a false figure as a user could be online for 5 secs which would trigger a 20 minute session.
Best to do the ping really.
All the other logic you have there seems fine.
Just spotted your other comment. Yes if someone leaves their browser open at the page then potentially this could be pinging all day. But then they maybe online so you'd have no choice but to presume that a session is active really. You could always add a bit of js that detects clicks and scrolling to determine activity.
IMHO, the best way to handle 2 and 3 is to have the client send a ping every x seconds, update last access time in DB, then have a logout function on the server side that looks for non-access within x amount of time, and update flag.
These automatic pings will make it seem like there is activity from the client when there may not be, and in this case add some events that capture mouse and keyboard activity. If they stop for some period of time, stop sending pings. Restart pings when activity resumes.
A ping is the only way that you will be 100% sure that the user is still there. Think of example where a user just shuts off the machine. You will not know that they are gone until 20 minute timeout expires. If you set your ping for 60 seconds, you will know very quickly is a user disappears.
I have an alert that pops up when the users session is about to expire and when it does expire. The issue is that if multiple tabs are open for the app, multiple alerts will get fired in succession which is very annoying.
I'd like to make a check on the backend for session information before showing an alert. That way if in one tab the session is about to expire (according to the front end), but it's not actually about to expire because you've been operating in another tab, the alert won't display and steal browser focus. Ideally I'd like this to remain as an alert so the first and proper display of the warning does take browser focus.
So is it possible to make a request like this without refreshing the session?
Trying to do this in JavaScript is silly - it will be really hard to keep the countdown timer in sync with the PHP session.
If you are implementing a hard timeout on the session then you must already be using a custom session handler - so simply implement a variant of that in your Ajax responder which does not lock or write back the session.
OTOH if you're not really implementing a hard session timeout, and you are not already using a custom session handler (which I suspect really is the case). Then just check the timestamp on the session file.
I'm looking for an event that will return when close page whether the user is connected to my site.
onbeforeunload does not help me because it is also activated in efresh, submit, browse from page to page on the same site.
There is no client side event that triggers when a user leaves your site for another site specifically.
If you want to know if users are online you can make repeated ajax calls on a timer, and use a server side session that updates a timestamp of the last request. Using this you can query the timestamps for example, get sessions where the timestamp is in the last 2 minutes.
If polling is an option and you have a server-side backend, you could make a keep-alive script polling the server every x seconds and add it to all pages on your site. If you do not receive enough calls (i suggest at least 3 or so), consider it as a signal the user has logged out. Of course this won't provide an immediate feedback, but should be reliable enough.
I'm coding a translation system for multiple messages.
I've a page with a table listing all the messages that need to be translated. When a translator click on a message to translate it, I lock it cause no other translator can be assigned to it.
The problem arises when a translator enters and instead to write something, leaves the page in an unconventional way like back button or closing the browser.
If this happens I want to unlock the message to make it available again to other translators.
How can I reach this behavior?
I know the javascript onbeforeunload event but triggers also every time a user refresh the page and this isn't what I want.
ty in advance
EDIT:
seems that implementing a js ajax call to notify every minute the server is the way to go. Now the question is how to handle the PHP server side?
You can use WebSockets, but in my opinion its a immature technology and still away from being firewall friendly.1
So, you can use HTTP polling. Use a JavaScript to make a HTTP request to the server from time to time, so it will show to the server the client is still in the page. The time will depend on connection, number of user's etc, but putting it before the keep-alive expires is a good idea as the TCP/IP connection is still open.
If the user leaves the page, the polling will not execute, and after not receiving the HTTP request for x seconds plus some time, the server can assume the user is not more on the page.
1 - Well its the firewall that is not friendly of WebSockets, this probably will change with time
What's wrong with using onbeforunload and asking the person if they really want to leave the page with unsaved changes?
I'd use the mentioned approach while proving a manual save button.
Also, a timeout on locks would help, so if the person has not edited the field for several minutes, it'd be unlocked and the person would be notified via a JS AJAX call.
EDIT: to implement the AJAX timer, I'd do the following:
save last access time to the translation item in a database or in a file on the PHP side
once every 30 seconds, do an AJAX call to a PHP script that will verify the last access time
depending on the result, return an "OK" or "TIMEOUT" message from the PHP script to the JavaScript part, which will then either do nothing (for OK) or deactivate the translation and inform the translation about the timeout
This question already has answers here:
How to know browser idle time?
(5 answers)
Closed 7 years ago.
In building a monitor, which would monitor any activity on the browser by the user, like click of a button or typing on a textbox (not mouse hovering on document). So if there is no activity from the user for a long time, the session will time out.
We need to do it without jQuery or anything such. I may use ajax. Java servlet in other end is preferable.
The problem with the approach you suggest is that the session will time out, even if the user is moving the mouse or typing in an input. So if you have a session timeout set to 20 minutes, and the user keeps typing for 21 minutes, the session will still time out, even though they have been "active". The only thing that will keep the session from timing out is a new request to the server.
Solution 1: Let the server be in control of the session timeout
Unless you are making Ajax-requests in the background, that will keep renewing the session, you could just set a JavaScript-timeout when the page loads, and alert the user that way. Unless you make other requests to the server, while the user is on your page, there is no need to make it difficult:
setTimeout(function () {
alert("You've timed out baby!");
}, 1200000); // 20 minutes in millisec (modify to your session timeout)
If the user visits another page or reloads the page, the session is renewed and the JavaScript timer is reset. If the user does no such thing, the session will time out at the same time the user gets her alert.
Solution 2: Let the client be in control of the session timeout
If you want the JavaScript to be fully in controll of how long the session lasts, so that it is renewed whenever the user types, moves the mouse or whatever, you will have too keep making Ajax-requests in the background to your server, so the session is renewed. (That could be an empty dummy request, just something that hits the server)
You would then have to track all actions you consider "user activity" (AnhSirk suggest one way in his answer) and reset the timeout timer whenever such an event occur. If the user is inactive for too long, you would then have to make an Ajax-request to a page on the server, that invalidates the session, and then you can alert the user that the session has timed out.