Save only changed objects on server : Restful service + angularjs - javascript

I display a list of posts on my page with a like button that the user can toggle on or off.
In order to throttle the traffic with my server, I would like to:
send updates for all the posts where the like status has changed at once in the same request
send updates for the modified posts only
update the like status each N seconds, and on page exit only. Not each time a user toggles a like button.
Is this possible with angularjs?

I've written up an example that can be seen here:
http://plnkr.co/edit/imMGTJ75mKJZT7ispD9E?p=preview
I've spent some time on it with commenting, and providing useful information that gets displayed on the page itself when it runs. Change around the delays if you'd like it to run slower if the messages are moving too quickly.
From your question it looks like you want to save when a user makes any changes to a particular post. You proposed checking every x seconds for changes, but this isn't ideal (though it would be simple to implement with a setInterval). You also mentioned saving the changes on page exit, but it's impossible to guarantee that something happens on page exit (a user loosing power for example).
To avoid the above, I would fire the ajax call when the user clicks the "like" button, but throttle them after the first click & store their changes while the throttle timer is running and push all their changes at once after the timer ends.
Here is what my plunker code does in a nutshell:
User "likes" or "unlikes" a post and it will make an Ajax call to the server with the new information on the post. At this point, any new "likes" / "unlikes" gets thrown into a "queue" of posts that need to get updated.
When the first Ajax call is successful, the throttle timer starts. In the example I've provided it is 5 seconds. Any changes to a post ("likes", "unlikes") will be thrown in that same "queue".
After 5 seconds is up, it will check the "queue". If it's empty, no action is taken. If it has items in it (e.g. posts that have changed), then it will make a second ajax call and update the posts on the server.
My example won't mirror what you're working on exactly, but it's the concept that matters. You could modify the code so it doesn't throttle for such a long time, or have it only throttle after x number of ajax calls in a certain amount of time, etc.

Related

How to set offline a User in the DB when it closes the browser?

i have a logout function that sets the User offline in my DB (mysql), but if it just closes the browser, in my DB the User is still online despite it's not , How can i manage this? How can i set the User Offline without press the logout botton? Cheers in advance !
Ps: Yes, i'm using SESSION
You can do it in following ways.
1) send the Ajax request to server every 5 seconds to update the current time.
2) and where you want to show offline just get records where current time is more than 5 seconds ago.
HI the only reliable way is to set an interval that calls the server and logs it in a database
var timeout = 15000; //milliseconds
setInterval( function(){
$.post('yoursite/keepalive' );
}, timeout );
Then you check the session on the server side you need a simple database table with the user id and a timestamp of the last time keepalive was called, then you just get the current time an there id ( from the session ) and save that. Then you can check if its been more then say like 20 seconds you will know they are gone ( should be updated every 15 sec ). Obviously you would need to have this interval on every page of your site to accurately track a user.
Things such as checking the session time, and unload are not accurate enough,
Unload is fired when any page is closed, so for example,
we have a user that has 2 pages open, they close one of them. the other page is already loaded so there is no traffic between client and server, and no way to know that page is still open
for Session time we have a similar problem, say someone is reading a long post on your page, They need to use the facilities and leave the page open. 30 minutes go by the come back and continue reading the post for another 10 minutes. now maybe the session has expired maybe it hasn't the fact remains they are still looking at your site, and you have no way to know it.
An interval will continue as long as the page is open and there are no javascript issues. A disadvantage of this is it will also keep their session updated ( you can get around this by sending the user id along with the ajax and not using the session, but that has other complications ) because you have that 15 second update you can check anytime if it has been more then 15 seconds. Say you want to display a list of online users to your other forum users, you just query for everyone with a current timestamp from that table, easy beazy.
As for the amount of time for the interval, you have to strike a balance between performance ( network traffic ) and how granular you need to know the information, if it's ok to only know if they logged off within the last minute then use that, if you can wait 5 minutes to know etc....
Really the Crux of the problem is how the server, and a client communicate. Right there is no two way communication like if your on the phone. It's more like a walkies talky where you have to say 10-4 and let go of the button for the other guy to talk. Essentially a client will make a request, that request is fulfilled by the server. that is the end of the communication and the state. Subsequent request state is maintained by using session so the next request uses that session to 'remember' the client. other then that there is no communication between client and server. There is no way to know they hung up the phone, for example, but to ask them if they are still there. ( this is an oversimplification because you cant send a request from the server to ask, more like they have to tell you they are not there, unless you use node.js or something like that ).
As #David has mentioned you could track this based on last activity, for that you would just need to know when the session was last updated. One of the easiest ways is to move the session into a database handler via http://php.net/manual/en/function.session-set-save-handler.php that way you can access when they were last active.
Using this vs ajax really depends on what you need to know, and how accurately. There is also the content of your page to weigh in. If you have a site that makes requests frequently it would be a better approach because you save on network traffic, for example. However, if you have long post someone could be reading for 20-30 minutes but want to know more frequent then that use ajax.
You can do it in many ways:
Launch an AJAX call on onbeforeunload javascript event. Prompting for a confirmation "Windows is closing, are you sure? YES/NO" should give you enough time to set the flag in the db, just be sure that if the user clicks "NO" you should unset your flag
Check session time... Add a var in your PHP_SESSION that is updated at every user event. If it becomes older than a preset threshold (i.e. 5 minutes), you can safely assume the user is gone
Example for onbeforeunload
function myConfirmation() {
return 'Are you sure you want to quit?';
}
window.onbeforeunload = myConfirmation;
You can try the javascript beforeunload event:
window.onbeforeunload = function() {
// Some AJAX request to logout.php or whatever script handles the logout
}
It will trigger when the user attempts to close the current window.
Watch out though, even if the user closes a single tab (your page), the event will be triggered, so if there are other tabs opened, so the browser will be, and you'll still get your users logged out.
Also, if several tabs of your website are opened, and you close one of them, you'll get your users logged out, which may not be what you want, so you'll probably have to find a way around to fix it.

Is it bad idea to make an AJAX post call every 2 secs?

If I make an AJAX $.post call (with jQuery) to a php file for updating a certain parameter/number, does it considered bad practise, dangerous or similar?
$.post(file.php, {var:var}, function(data){
// something
}, json);
It would be a single user on a single page updating a number by clicking on an object. For example if user A is updating a certain number by clicking on an object user B should see this update immediately without reloading the page.
It depends on 3 main factors:
How many users will you have at any given time?
How much data is being sent per request on average?
Given 1 and 2, is your sever set up to handle that kind of action?
I have a webapp that's set up to handle up to 10-20k users simultaneously, makes a request each time the user changes a value on their page (could be more than 1 req per second), and it sends roughly 1000 bytes on each request. I get an average of 10ms response time, however that's with node js. Originally I started the project in PHP but it turned out to be too slow for my needs.
I don't think web-sockets is the right tool for what you're doing, since you don't need the server to send to the client, and a constant connection can be much more expensive than sending a request every few seconds.
Just be sure to do lots of testing and then you can make judgements on whether it'll work out or not for your specific needs.
tl;dr - It's not a good idea if your server can't handle it. Otherwise, there's nothing wrong with it.
Another solution could be, to cache user actions in local storage/variables, and send them all at once every 10-15 seconds or so, then clear the cache, when sending was successful.
In this case you should also validate the data in local storage to prevent tampering.

Get dynamically changed data from web page using javascript / jquery

I'll be as direct and as specific as possible.
I'm trying to create Greasemonkey addon that would create graph of winnings/loses on: dead link
As you can see, site has front page which dinamicly shows results of wins / loses and how much did which user win/loose. What I'm trying to do is catch every new entry so I can draw some grapsh and or statistics for user / users.
When I access div/span that should have data, it turns out to be empty. I know that reason behind this is that all divs with data relevant to me are empty on load and that they get populated later on.
What I don't know is how to access that data. I can see (using firebug console) that there are GET requests executed all the time and that in those get requests is data that I need.
Can someone tell me or at least point me into right direction, how to access that data every time it gets refreshed / inserted?
You can try using the $.ajaxSuccess function to specify a function in your script to be called everytime an ajax request completes in the main page. This'll be fired for every successful ajax request, whether it pertains to the data you're talking about or not, but should allow you to re-scrape that section of the document to grab any and all data in it after every successful request. You may want to wrap your callback function in a setTimeout of some kind to make sure their own callbacks have a chance to fire and inject/modify the content before you scrape it. It should still seem instantaneous to the user if you set a timeout of, say, 1-10ms.
http://api.jquery.com/ajaxSuccess/

undo action. delay ajax call for set time or until next action

I would like to setup and undo feature that delays my ajax call a set amount of time and gives the user an opportunity to abort the ajax call before it gets called. I would also like to stop the delay and continue with the most recent ajax call if another action is triggered.
For example,
If i sent an email and I'm given 5 min to undo this action, I can send another email to send the previous email and to give this new email 5 min to undo.
I was wondering how I would be able to do this?
You can try to encapsulate the actions and show use the pending actions which use can commit by clicking a button. This way they can any time remove the pending action.
Another way is to create undo action (like if a block of text is deleted, keep the deleted text with position information) that can be executed later to bring system back to previous state.
But if it is something like email sent or data saved to database things get complicated and queuing up pending changes is a better way.
There is an undo/redo module for YUI library which you can explore.
Here is some pseudo-code:
User clicks to send
If there is a previous one saved ...
clear the timeout away
call the send function which will ...
retrieve the saved one
if it hasn't been erased ...
erase the saved one
call ajax to send it
Save the current one away
set the timeout to call the send function (defined above)
Note that "saving" and "retrieving" is simple here. Store it to the 'savedEmail' variable and get it from there. Erasing means you set the 'savedEmail' variable to null.

Alternatives to using meta-refesh for updating a page

In the past, when I've covered events, I've used a meta-refresh with a 5 minute timer to refresh the page so people have the latest updates.
Realizing that this may not be the perfect way to do it (doesn't always work in IE, interrupts a person's flow, restarts things for people with screen readers, etc.) I'm wondering if there's any other way to do handle this situation.
Is it possible to have something like ajax check every few minutes if the html file on the server is newer and have it print a message saying "Update info available, click here to refresh"?
If that's crazy, how about a javascript that just counts down from 5 minutes and just suggests a refresh.
If anyone could point me to tutorials or code snippets I'd appreciate. I just play a programmer on TV. :-)
Actually, your thought on a timed Ajax test is an excellent idea. I'm not sure that is exactly what StackOverflow uses, but it checks periodically to see if other answers have been posted and shows the user, on an interval, if there are updates.
I think this is ideal for these reasons:
It's unobtrusive - the reader can easily ignore the update if they don't care
It won't waste bandwith - no reloading unless the user chooses to
It's informative - the user knows there's an update and can choose to act on it.
My take on how - have the ajax script send off the latest post id to a script that checks for new scripts. This script can query your database to see if there are any new posts, and how many there are. It can return this number. If there are new posts, show some (non modal) message including the number of updates, and let the user decide what to do about it.
setInterval(function() {
if (confirm("Its Been 5 Minutes. Would you like to refresh")) {
window.location.reload(true);
//Or instead of refreshing the page you could make an ajax call and determing if a newer page exists. IF one does then reload.
}
}, 300000);
You can use the setInterval function in javascript.
here's a sample
setInterval("refresh function", milliseconds, lang);
You will use it passing a name to a function that actually refresh the page for the first param and the number of milliseconds between refresh for the second param (300000 for 5 minutes). The third parameter lang is optional
If the user would be interacting with the scores and clicking on things it would be a little rude to just refresh the page on them. I think doing something like a notification that the page has been updated would be ideal.
I would use jQuery and do an ajax call to the file on the server or something that will return the updated data. If it's newer than throw up a Growl message
Gritter - jQuery Growl System
Demo of what a Growl is using Gritter
A Growl message would come up possibly with whatever was changed, new scores and then an option within that message to refresh and view the new results.
jQuery Ajax information

Categories