Javascript - Increase time dynamically - javascript

I have a dashboard page, where I have some time values that come back from the server. These times are in the format: HH:MM:SS (13:05:01, for example). But that value only refresh when then user reloads the page. I would like to do some javascript to keep that value going on... what's the easiest easy to do that? Thanks in advance!

Can you give me a valid reason to spam the servers with requests for time over and over again when the user machine has high probability of having perfectly valid time - is connected to internet and unless user has not messed with it it's correct.
(You might have to offset for zones, not 100% about that)
Downsides of approach to ask server over and over for current time:
You will suffer from latency
You will spam server without valid need
Ability to scale is sinking very fast both by items and users
If you need to check user time matches yours, do a 1 request at the start and then compare times with a bit of offset allowed. If times don't match set the correct time on front from back and display user device time +- whatever the difference was. If they match close enough display user's device time.
Deletes all the negatives. Adds no new negatives.
EDIT upon comment:
Oh, that makes more sense. You can query server on reload but if you expect to reaload a lot (and you need a time to be static after once being set up) you can use localStorage to store it on new browsers or cookies (work for older browsers as well).
For something that is not likely to change I would not query the server again if I don't need to. In case you need / wanna query the server again specifficaly when page loads or reloads you can add this to element on that page onload="myFunction()"
In myFunction handle to call to the back and binding to text of element displaying it.

Personally, I would go about doing it with setInterval, just set it to run the function that updates your time, and set the interval, to 1000 (milliseconds) for it to change every second. You can look Here for more info.

Related

I want to popup a window 3 minutes after the user enters the site

As the title says i want to pop up a window 3 minutes after the user enters the site. The problem is since a user wont stay on a single page for 3 minutes. I cant use javascript. since he might navigate to different pages in my website. I tried using setTimeout but it wont work if i navigate to a different page the code gets refreshed again.
Sounds like a good use for sessionStorage:
On initial page load, check for existence of sessionStorage item
If the item doesn't exist, populate it with the current date/time
If the item does exist use setInterval to poll and compare the time, say every 100 ms. If 3 minutes has passed, pop the message.
sessionStorage values will persist across pages and page reloads.
Example:
// Save date to sessionStorage
sessionStorage.setItem('your-key', new Date());
// Get saved date from sessionStorage
var date = sessionStorage.getItem('your-key');
You'd probably want to fall back to localstorage and then cookies if you use this method.
You can use session at server side. Put the session start time in a session variable. Each time a new page is requested, you can return the session start time. Then, feed this DateTime as well as current server DateTime to your global javascript function which will take care of further calculations as well as displaying the popup.
Remember here that I am fetching current DateTime also from server since javascript detected DateTime, in most cases, is different than the server DateTime (due to hosting location, etc.). With this solution, The only demerit is you won't be able to track the lagging caused by client server roundtrip.

Killing session when browser is closing

I need to kill the session when the user closes the browser or redirects into some other page.
I can see the following options of achieving this functionality:
Use no session login. It's not my case, because I'd have to change a lot and I also use sessions for some other data.
I could use something like this:
window.onunload = window.onbeforeunload = (function () {
...
})
And from this code call the action that cleans the session and performs logoff.
Sounds nasty but what is also important - this JavaScript code works only in IE.
I could create some nasty code that uses some dummy calls, let's say every minute, just to say the server that the user is still alive.
But it's really nasty. It would use useless load on the server, lots of useless calls and in the case if some call was lost(because of the connection issue or something) the user would logg off.
Any other options?
You've left off #4: Don't do anything, have sessions time out after a reasonable period (say, 20 minutes); if they try to do something on that page after being gone for 20 minutes, just show a page telling them their session has expired and to log in again. That's usually the simplest option.
If you don't want to do that, #3 is really your only viable option, but once/minute is probably overkill. Set the session timeout to 20 minutes, remember when the user has done something, and if they're idle for (say) 15 minutes do a proactive call on their behalf. But even then, I'd limit how much I'd do this, after a couple of hours you might want to just redirect them to the login page.
I think this answer is the right way to go:
In javascript, how can I uniquely identify one browser window from another which are under the same cookiedbased sessionId
Set a unique window id:
window.windowIdClient = "{978d-478ahjff-3849-dfkd-38395434}"; //or another randomly generated id.
Store that windowId in the database, along with the ip-address and the session-id. If those three do not match than the user is logged out.
In addition, if didn't think of T.J. Crowder's option, I use it myself.

Triggering a DB call on browser leaving current page?

I've got an application that I intend to set a lock flag in my database that would exclude others from viewing that same page if set.
However, once set - I have no idea how to "unset" it. I could make it up to the user to unset the flag, but that seems unnecessary.
I'd want to simply look for the browser to leave the page, make a call to the database, and unlock the page.
How does one do this "type" (not looking for the exact way) of thing with JSF/Javascript/jQuery (all options)
There's really not a reliable way to do this, that I've seen anyway.
You can use the browser's onbeforeunload event to tell the server, "Hey I'm leaving the page now.". The issue is you can't actually block the page from unloading. If the user is actually closing the browser, any open sockets are going to be closed immediately. Your web server may or may not get the request in time. I've had very flaky results with this approach.
One approach that might work is to employ some sort of timeout mechanism. The page would ping the server every 30 seconds or what not, saying "I'm still here." If the server did not get this update after a few minutes, it would invalidate the session and free up that document. Perhaps this could be optimized by checking for the last ping when someone new came along. One issue with this is if someone left the page, the next user might have to wait a minute or two before they could go to the page. You'd then have to find a ping frequency that doesn't flood your server with traffic, but also doesn't make the next user have to wait too long.
It's also possible to combine these two methods. When the user leaves the page, trap the onbeforeunload event and immediately invalidate the session. However, if it didn't work, the session would time out after a minute of not being pinged.
Are there better solutions?
If you really need to lock a document in a web app so multiple users can't edit it, you might want to investigate your overall design. Are you afraid of users clobbering data? If so, maybe employ a mechanism that can resolve merge conflicts, or detect if both sets of changes can be combined.
If you wanted to go truly Web 2.0, you could design something similar to Google Docs, where changes appear live as they're made. No need for a Save button anywhere!
Sending a "keep-alive signal" might be an option. Something along these lines on the frontend side, combined with session cookies.
setInterval(function() {
var img = new Image();
var src = "http://examle.com/keepalive.gif?cachebuster=" +
Math.ceil(Math.random() * 10000 );
}, 1000);

Monitoring User Sessions to Prevent Editing Conflict

I'm working on something similar to a pastebin (yeah, it's that generic) but allowing for multiple user editing. The obvious problem is that of multiple users attempting to edit the same file. I'm thinking along the lines of locking down the file when one user is working on it (it's not the best solution, but I don't need anything too complex), but to prevent/warn the user I'd obviously need a system for monitoring each user's edit sessions. Working with database and ajax, I'm thinking of two solutions.
The first would be to have the edit page ping the server at a arbitrary interval, say a minute, and it would update the edit session entry in the db. Then the next time a script request to edit, it checks for the most recent ping, and if the most recent was another arbitrary time ago, say five minute, then we assume that the previous user had quited and the file can be edited again. Of course, the problem with this method is that the assumption that the previous user had quited is simply an assumption. He could be having flaky wi-fi connection and simply dropped out for ten minutes, all the time with the window still open.
Of course, to deal with this problem, we'd have to have the server respond to new request from previously closed sessions with an error, telling the client side to point out to the user that his session has ended, and then deal with it by, say, saving it as another file on the server and asking the user to manually merge it, etc. It goes without saying that this is rather horrible for the end user.
So I've came around to think of another solution. It may also be possible to get a unload event to fire when the user's session ends, but I cannot be sure whether this will work reliably.
Does anybody has any other, more elegant solution to this problem?
If you expect the number of concurrent edits to the file to be minor, you could just store a version number for the file in the db, and when the user downloads the file into their browser they also get the version number. They are only allowed to upload their changes if the version number matches. First one to upload wins. When a conflict is detected you should send back the latest file and the user's changes so that the user can manually merge in the changes. The advantage is that this works even if it's the same user making two simultaneous edits. If this feature ends up being frequently used you could add client-side merging similar to what a diff tool uses (but you might need to keep the old revisions in that case).
You're probably better off going for a "merge" solution. Using this approach you only need to check for changes when the user posts their document to the server.
The basic approach would be:
1. User A gets the document for editing, document is at version 1
2. User B gets the document for editing, document is at version 1
3. User B posts some changes, including the base version number of 1
4. Server updates document, document now at version 2
5. User B posts some changes, including the base version number of 1
6. Server responds saying document has changed since the user starts editing, and sends user the new document, and their version - user will then need to perform any merging of their changes into document version 2, and post back to the server. User is essentially now editing document version 2
7. User A posts some changes, including the version number of 2
8. Server updates the document, which is now at version 3
You can still do a "ping" every minute, to get the current version number - you already know what version they're editing, so if a new version is available you can let them know and let them download the latest version to make their changes into.
The main benefit of this approach is that users never lock files, so you don't need any arbitrary "time-outs".
I would say you are on the right track. I would probably implement a hybrid solution:
Have a single table called "active_edits" or something like that with a column for the document_id, the user, and the last_update_time. Lets say your ping time is 1 minute and your timeout is 5 minutes. So a use-case would look like this:
Bob opens a document. It checks the last_update_time. If it is over 5 minutes ago, update the table with Bob and the current time. If it is not, someone else is working on the document, so give an error message. Assuming it is not being edited, Bob works on the document for a while and the client pings an update time every minute.
I would say do include a "finish editing" button and a onunload handler. Onunload, from what I understand can be flaky, but might as well add it. Both of these would send a single send-only post to the server saying that Bob is done. Even if Bob doesn't hit "finish editing" and onunload flakes out, the worst case is that another user would have to wait 5 more minutes to edit. The advantage is that if these normally work (a fair assumption) then the system works a bit better.
In the case you described where a Bob is on a bad wireless connection or takes a break: I would say this isn't a big deal. Your ping function should make sure that the document hasn't been taken over by someone else since Bob's last ping. If it has, just give Bob a message saying "someone else has started working on the document" and give them the option to reload.
EDIT: Also, I would be looking into window.onbeforeunload, not onunload. I believe it executes earlier. I believe this is the function website (slashdot included) use to allow you to confirm that you actually want to leave the page. I think it works in the major browsers except Opera.
As with this SO question How do you manage concurrent access to forms?, I would not try to implement pessimistic locking. It is simply too difficult to get working reliably in a stateless environment. Instead, I would use optimistic locking. However, in this case I used something like a SHA hash of the file to determine if the file had changed since the user last read from the file. For each request to change the file, you would run a SHA hash of the file bytes and compare it with the version you pulled when you first read the data. If had changed, you reject the change and either force the user to do their edits again (pulling a fresh copy of the file contents) or you provide a fancier conflict resolution.

How to detect browser closing?

In my web app, when a user logs in, I add his Id to a vector of valid Ids in the servlet, when he logs out, I remove his Id from the vector, so I can see how many current users are active, if a user forgets to log out, my servelt generated html has :
<meta http-equiv="Refresh" content="30; url=My_Servlet?User_Action=logout&User_Id=1111">
in the tag to automatically log him out.
But I've noticed many users are there for ever, never logged out. I found out why, by closing their browsers, they never manually or automatically logged out, so their user Ids will never be removed from the valid user Ids vector.
So, my question is : how do I detect users closing their browsers, so my servlet can remove their Ids from the vector ?
I see some light at the end of the tunnel, but there is still a problem, my program has something like this :
Active User List :
User_1 : Machine_1 [ IP_1 address ]
User_2 : Machine_2 [ IP_2 address ]
User_3 : Machine_3 [ IP_3 address ]
...
How do I know, from the session listener, which user's session has ended and therefore remove him from my list?
I was hoping when the session ends, the HttpServlet's destroy() method would be called and I can remove the user Id in there, but it never gets called when user closes his browser, why? And is there any other method in the HttpServlet that gets called when a session closes?
There is no way to know on the server-side (unless you are using some JavaScript to send a message to the server) that the browser has closed. How could there be? Think of how HTTP works - everything is request and response.
However, the application server will track when Sessions are active and will even tell you when a Session has been destroyed (such as due to time-out). Take a look at this page to see how to configure a HttpSessionListener to receive these events. Then you can simply keep track of the number of active sessions.
The number of active sessions will lag behind the actual number of current users, since some period of (configurable) time has to elapse before a session is timed out; however, this should be somewhat close (you can lower the session-timeout to increase the accuracy) and it is a lot cleaner and easier than 1) tracking Sessions yourself or 2) sending some asynchronous JavaScript to the server when a browser is closed (which is not guaranteed to be sent).
I suggest you remove the ID when the Servlet engine destroys the session. Register a HttpSessionListener that removes the user's ID when sessionDestroyed() is called.
Diodeus's idea will only help you detect that the session is over more immediately.
in JavaScript you can use the onbeforeclose event to pass a call back to the server when the user closes the browser.
I typically use a synchronous Ajax call to do this.
I had to do that recently, and after some searches, I found some solutions on the Net... all of them non working universally!
onbeforeclose and onclose events are used for this task. But there are two catches: they are fired when the user reload the page or even just change the current page. There are tricks to see if the event is actually a window/page/tab closing (looking at some Dom properties going haywire on closing event), but:
They are browser dependent
The tricks are undocumented, thus brittle
And actually they vary along the browser version/update...
And worst of all, these events are now ignored by most modern browsers, because they have been abused by rogue ads popping out windows when browser was closing. They are not fired in Safari, Opera, IE7, etc.
As pointed out, most Web applications with login destroy the user session after a while, eg. half an hour. I was asked to logout on browser closing to free faster a precious resource: licenses. Because users often forget to log out...
The solution I gave was to ping with an Ajax request (sending the user ID) the server on regular intervals (say 1 minute). If the server receives no ping for, say, 3 minutes, it disconnect the user.
There is no foolproof way to do what you're trying to do, but both sblundy and Diodeus have plans that will cover most circumstances. There is nothing you can do about someone who turns off Javascript in their browser, or their internet connection goes down, or their power goes out. You should just cull sessions after a certain period of inactivity (which I think is what sblundy's suggestion of listening for session destruction will do).

Categories

Resources