Resuming JS timer on accidental power failure - javascript

I am making an online quiz app having a timer which is implemented through JavaScript. If accidentally, the browser closes due to power failure, I intend to resume the timer from the time-point when the browser was closed. Right now, I am recording time only at the end of the quiz in a database using PHP/AJAX. How can I resume from the exact time when the user closed the browser?

The issue with a power failure is that you will not be notified in advance of the power going out so there is no opportunity to save state upon the power failure.
Thus, the only way to have any idea when the power went out is to be continuously saving state every N interval of time. Then, when the power goes out and is then restored, you can look at the last saved state. It won't be perfect, but will be the best you can do.
Your three options for saving state are:
Set a cookie every minute (or some period of time with the running count of time in it).
Save the same state to local storage (newer browsers).
Do a form of "auto-save" of the running time to your server with a regular ajax call (every few minutes).
The advantage of options 1 and 2 is that it's all client-side so saves are quick and don't load your server. The disadvantage of options 1 and 2 are that they could conceivably be manipulated by a client trying to game the system.
There's a small danger that even the local state in options 1 and 2 might not be saved properly in a power outage, but as best I know most browsers do persist this to disk when it's saved so that it's reliable even if the browser later crashes.

You can subscribe to the window unload event, but I'm not 100% sure this will be fired on a power failure shutdown.
Perhaps a better solution would be to poll the user during the course of the quiz by a setInterval which can fire off every 1000ms (or however frequently) and set/update a cookie.

Related

Implementing Presence - When to Change Status to Offline

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.

How to realize cross page timer?

I am trying to realize booking system on my site. I want to allow user to book terminal entity for 10 minutes. Entirely, flow is enough big and goes over several pages.
While user navigate on this flow he should see how many time he has to complete operation.
Please advice me how to realize cross page timer.
I think the most straightforward way would be to create a cookie or an item in the user's localStorage which contains the start time of the transaction. Upon loading the page, you check for the existence of this value and compare it to the current time, if it exists.
You can use setTimeout or setInterval to run timers in the browser. However, a browser window is not guaranteed to continue to execute when it is not active. If the user hides the browser or goes to another application, the application cannot be sure that the timer is still running.
There is a newer specification for threading called web workers, which may help to alleviate the setTimeout problem.
https://developer.mozilla.org/en-US/docs/Web/API/Worker
As an alternative, I would suggest to store the start time on the server and continuously check the current time against it with polling HTTP requests. Or maybe just check it before they submit.
Or as stated by #sholanozie, store it in a browser cookie and just keep checking that.

Detecting user inactivity over a browser - purely through javascript [duplicate]

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.

Keeping track of online/offline status in real-time with NowJS/Node.js?

I've got a site where users login and are connected to NowJS on all pages. I'd like to be able to keep track of their status (online/offline) in near-realtime, but I'm not sure the best way to do this. My initial thought was to just use the connect and disconnect events, but this won't work because those get fired each time the user goes to a new page (since the socket connection is closed while the new page loads).
I've got it somewhat working where I record a timestamp in the database entry for that user on the disconnect event, and then when the connect event fires I check if they've accessed the site within the last 30 seconds. If they haven't, I can assume they are starting a new session. On the disconnect event I use setTimeout to see if they are still online 30 seconds from now, and then set their status to offline if not.
While this mostly works, it seems somewhat hacky and has several edge case issues that could be problematic (not to mention the fact that your going to have a new timeout server-side on each page view). Is there a better way to do this that I'm just overlooking?
The right way to do this depends on more than just 'whether there is an open connection'. Are you trying to display to other users whether someone is around/available for chat/whatever? Then you might also consider an inactivity timeout on the page itself (to capture the times when people walk away from their computer without closing the page). If you're doing something else, like metering usage, you might want a different mechanism.
I think the solution here is extending the timeout option for Socket.IO (NowJS uses this internally) or use your hacky solution with setTimeout.
Honestly that seems the best solution considering users can move to another page quickly.
What I ended up doing was creating a global object that holds the persistent ID for the user (so in this case their ObjectId in MongoDB) as the key and the reference to the setTimeout as the value. I then do clearTimeout on a 'connect' event and delete the key from the object when they are considered offline.

Server polling intervals for a javascript chat client

I'm building a basic little AJAX shoutbox/chat for my website, but I'm not sure exactly how to implement the server polling.
Here's the basic program flow I'm thinking of:
User comes to page and is shown the last 10 messages
To get messages sent by others, the client javascript would request a URL with a timestamp parameter (set to the value of the last message the client received)
The server returns all messages (up to a max of 10) since that timestamp.
The only issue is how often to poll the server. Obviously it should poll each time a new message is added, but when you're just reading others' messages it needs to automatically update.
Should it be a set time limit? eg: every 10 seconds. Or, should it vary depending on usage? eg: Check after 5 seconds. If there's no messages, don't check for another 10 seconds. If there's still no new messages, check in 15 seconds, then 20, up to maybe once every 30 seconds max. Each time there's a new message detected reset your timer back down to 5 seconds and start again.
I'm just concerned about putting unnecessary stress on the server, considering that we could have hundreds of users concurrently online.
...or have I got the whole thing wrong? Is there a better way to implement a basic javascript chat?
You might want to look into what are known as Comet programming techniques to stream information down to your users, rather than having the client poll the server. This is actually a family of techniques, some of which may work better than others depending on the circumstances, such as what kind of server you're using and what kind of client compatibility you need.
If your server can handle a large number of open connections at a time (as in, it does not use an entire thread or process per connection, such as nginx or an erlang based server), you may wish to use a long polling technique, where as soon one message is received, the client immediately requests another message. If there are no messages available, the server simply keeps the connection open, possibly sending occasionally dummy data as a keepalive, until a message becomes available.
Comet, described by Brian is a nice technique, but requires session support on the server, which is probably more advanced than you care to implement for a simple chat box.
The best way to implement polling intervals is to imagine you having a chat window which you can minimize to do other stuff, or open to see if you have new messages. When you are in the middle of a conversation, you'll switch to it (poll) frequently. If you don't get any messages for a while, you will start looking rarer and rarer until you only check it occasionally.
Assuming you don't need to do real-time typing, you can probably poll every 3 seconds or so when at peak activity, and if nothing shows up for 5-10 polls, start to crank the interval up (perhaps doubling it every time) until it hits 30-60 seconds. Getting a message back should reset the poll interval back to a few seconds, while sending a message should poll instantly, but probably doesn't need to effect the frequency of polling otherwise.
Honestly, if you are implementing a “basic little AJAX shoutbox/chat”, things like Jabber, Comet etc are overkill for you. These things will require you to run additional
servers/proxies to take the load of the app server and db.
When you think about stuff like presence management (“Joe is typing...”), then things get overly complex for your app (considering “chat” is not your prime focus).
Think about adding widgets from providers like Meebo and Userplane. Once you scale think about the Jabber and the like…
You should check to see if the other user is typing every 5 seconds or so, if the other user is typing, then you can check every 1 second to see if the user has sent a new message. Really though, you should be able to check every 1 second to see if other user is typing and if they are then every .25-.5 second check to see if new message has been sent. With broadband being so generally accepted on the inet, shouldn't be a problem. Go with the longer poll timeout for a dial-up access.
This is a very hard question, keep abuse in mind. Malicious users will hit you as often as possible, with the earliest timestamp faked so as to cause stress on your DB server. Be sure to validate that timestamp, or ignore it, because shouldnt everyone be in the same time anyway?
You can send the polling interval to the user as a function of the other user's response time. That's the best kind of dynamic I think.
http://jabbify.com/home/comet_service
This is a free comet based chat service by the guys who did the jmvc framework. Haven't tried it yet, but looks promising.
The professional way of doing this is with a WebSocket javascript connection. You can use a free service like https://socketsbay.com/ for example, and connect using
// Create WebSocket connection.
const socket = new WebSocket('wss://socketsbay.com/wss/v2/[ChannelId]/[ApiKey]/');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
You can forget about server pooling time because it will be realtime.

Categories

Resources