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.
Related
I want to make a custom tracking system for web events. I have looked into multiple per-excsiting systems, but I want something terribly simple - yet very accurate.
I want to be able to track the following:
Page view even
Time on that page
or:
Video started playing event
Time of video watched
My first initial thought was to do a simple javascript reporting back to the server, but what happens if the user closes the window? How do I know they stopped viewing? And how can I get accurate measurements down to 1/10th of a second? So I thought of a websocket solution, as it know when a user has discounted. I ended up with Socket.io, but I want to make sure there is no better or smarter way to achieve this?
How would you approach his challenge? What is the smartest way to engineer this?
A Websocket connection which reports back to the server frequently was my first thought as well, but if you send 10 messages every second, even that might be too much for a websocket, especially when connectivity isn't top-notch.
Since the server doesn't require the information absolutely immediately, consider batching requests instead - save/update the information into Local Storage every 0.1 seconds, but don't send it to the server then - instead, every 30 or 60 seconds, or on pageload, take the current data in Local Storage and send it to the server, and clear Local Storage so that the next request a minute from now doesn't send duplicate data.
I am attempting to implement the Instagram like feature that destroys videos (stories) after 24 hrs, but in my case its just the duration of the video. Using this example I am trying to allow users to only view a story once, meaning no replay. Even upon refreshing the page, it should not load.I tried localStorage but couldn't work.
I don't think you can write a foolproof solution to this without some server-side intervention.
Yet, if you think localStorage based frontend solution is enough for you (which I don't recommend), you can:
Maintain a sorted list of MD5 hash of the videos in your localStorage.
When your react app loads (in componentDidMount), load that list into memory. Now you can search this ordered list with your current video MD5 hash to decide if you are to play this video of not.
When you play a video, update the list of MD5 hashes both in memory and localStorage.
If your server removes the videos after 24 hours or some interval like that, you should store the time in local storage too to cleanup your localStorage or it'll be ever growing in size.
You can't truly control that video. Once it's sent, it's sent and viewable. But, you can come close.
First, continue with your UI mechanism like you plan to with LocalStorage or similar. This is to prevent normal users from viewing the video over and over again.
Next, use Encrypted Media Extensions to implement DRM. This makes it harder to get at the raw media, and gives you more control over the timing of things. Note that this is a huge hassle, so make sure it's worth it before you go down this road.
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.
Is there any way to detect when a user leaves a page, no matter if it's by closing the browser, entering a new URL in the address bar, clicking on a link that redirects to other domain, etc. ?
The main purpose of this would be to perform some activities such as:
sync with the server some data that resides in the client side
clear server session
I was trying with the window's unload and beforeunload events, and reading other questions like:
Best way to detect when a user leaves a web page?
//
Is there any way to know that user leaving a page with asp.net? but I didn't find the answer I would expect.
Here is a simplified js snippet to understand what I was trying:
window.onunload = function(){
if (theConditionThatINeed){
doThings();
SyncWithServerAndAbandonSession(url, localObjects);
}
else {
doNothing();
}
}
I don't want to display any kind of confirmation before the user leaves, so I think that the onbeforeunload won't help me here.
Supposing that the answer is "there is no way to do such thing", what would be the recommended practice to accomplish the synchronization and session clearing that I want?
The primary browser that I support is IE >= 7
As you already read, it is not reliably possible to detect whether the user leaves your page.
Generally it is not good practice to store any unsynced state on the client side. Browsers are easily closed or crashed.
You can send yourself ajax keepalive messages via javascript, in case the user does anything on your page. Again, very unreliable, wasteful and hacky.
Auto-Sync after a short timeout.
Take a look at RESTful web applications. The concept is interesting, and, very superficially spoken, discourages keeping state information on the server. You can apply this to the client as well.
This usually results in keeping state information in the URL. The URL tells the server anything it needs to know to service the request, it should not need a memory (the session) of any previous activity.
I try to only keep the user identification info in the session. I would get rid of this too, but some tools and libs need the user in the session.
I'm currently fooling around with AJAX. Right now, I created a Markdown previewer that updates on change of a textarea. (I guess you know that from somewhere... ;-) ).
Now, I'm trying to figure out, how to update a page upon an event is fired from another client. So to say an asynchron message board. A user writes something, an event is called, the post is written.
But on the other clients' pages, the new post is of course not yet available until they reload and get the updated list of posts from the database.
Now, how can you get this to work asynchronously? So in that moment when one client does something, the other clients all get to know that he did something?
I don't think this can be done completely in AJAX, but I also have no idea whatsoever how to implement this on server-side, as it would require a page reload to inform the other clients of the event.
I'm thinking of creating a file or database entry that hashes the current state of data. Whenever a client loads the page, he saves this hash. Then, a timer (does this exist in JavaScript?) checks for the hash every few seconds.
As soon as anyone changes the databse, the hash is recalculated. If the script sees that the hash was changed and is different to the one saved, it reloads the contents form the database and saves the new hash.
Is that even going to work?
Polling that is light as possible is really the best solution here. Even if you did use a socket or something... That's still basically a live connection waiting around that will likely have to poll itself (albeit in a more effecient way).
20 queries in 10 minutes that have responses like {"updates":false} shouldn't even be putting a dent in your application. I mean imagine someone browsing your site requesting 20 pages and the related images/scripts/etc (even if some caching is involved), there could easily be hundreds of requests requiring all sorts of wasted database queries to information to be displayed on the page they don't actually care about.
You could use polling. For example each client might be sending continuous AJAX requests to the server say each 30 seconds to see if new posts are available and if yes, show them:
setInterval(function() {
// TODO: Send an AJAX request here to the server and fetch new posts.
// if new posts are available update the DOM
}, 30 * 1000);
On the other hand when someone decides to write a new post you send an AJAX (or not AJAX) request to the server to store this post in the database.
Another less commonly used approach is the concept of Comet and the HTML 5 WebSockets implementation which allow the clients to be notified by the server of changes using push.