Ajax auto updates and server load - php

I have a project that needs a sort of shopping cart that is always available at the top of the screen. Whenever someone hovers over the "cart" icon, a list of everything that's inside is shown.
However, if an user has two tabs of my site open, and in one of them something is added to the cart, the other one will be outdated and a refresh will be required.
My question is: if I use AJAX to constantly update the list of items (which will require sessions and database checks), will it be a big enough load on the server (or even on the browser) for it to be a problem, or is this common practice? If it is a problem, what other ways can I go so every tab an user opens is always updated?
If someone could show me the path so I can study more about it, even the name of what I should look up, I would be really grateful. Thanks.

there is no load on browser, just one more request in server ... maybe these requests are useless,
there is another way name server push
APE (Ajax Push Engine) :: Comet server :: Real time data streaming ->
http://www.ape-project.org/
nginx_http_push_module - Comet For The People -> http://pushmodule.slact.net/
node.js -> http://www.nodejs.org/
Socket.IO: the cross-browser WebSocket for realtime apps. ->
http://socket.io/
Comet with Nginx and jQuery | Coach J ->
http://blog.jamieisaacs.com/2010/08/27/comet-with-nginx-and-jquery/
if your request count is more than your server power use this way but if you have little request and not important you can use server pull frequently

Ajax is the solution here - it has a very light footprint.. as long as you don't use it indiscriminately, it is pretty much the same as reloading the page (much less if done correctly as its serving a smaller document). In fact, research has shown that ajax can cut the server bandwidth usage by over 60%.
You can read about the speed issue specifically here.
I learned Ajax over at Tizag, they have a brilliant Tutorial.
Hope this helped :)

you can make the ajax call on an interval to load the div with latest data. Something like this
(function getLatestCart(){
setTimeout(function(){
$("#latestCart").load("getCartDetails.php", getLatestCart);
}, 10000);
})();
this will call the method on every 10 sec(you can change the time interval) and load the latest cart to the div with id latestCart.

You can track locally this changes.
Use UserData (IE7 and down) or domStorage with updated data, and check every 10-20 seconds if the data was changed.

Related

PHP/JavaScript - detect which users currently have the page open

I want to make a page that will show all the users who are looking at that page right now. Ideally, a database would store which users are on the page and websockets would be used to update when users enter and leave.
The problem is that I don't know how to tell when users are viewing the page. I was thinking that I would be able to tell when they arrived and when they exited and add/remove accordingly. It's easy to tell when they arrive; however, it's difficult to tell when they leave - especially because users might do something like open multiple tabs, close one but keep the other open.
What is the best way to do this? I am using PHP as my server-side language.
You can use the blur and focus events on the window to toggle a variable. However, IE does some quirks which you will need to work around.
As a fallback to not working focus events, you might add a mousemove handler to the document. This might also throttle an automatic timeout which detects the loss of focus just by the fact that there was no user interaction for a specific period of time. However, you will never be able to detect a distracted user that has the site open but looks at something else...
To detect the window closing, you can hook on the unload event. This might be unreliable, but as you are using Websockets your server can easily detect a closed connection.
Well, one thing you could do, especially if you are using websockets is do a heartbeat/ping to the server every few seconds if you really wanted. If you don't get that heartbeat, you know they are not on the page anymore.... however, getting a response doesn't mean they are looking at the page, it would just mean that it is open, possibly in another tab. There is no way that I know of that will send a response to the server if the person loses focus on the page and opens another tab/window.
As Tim mentioned, Firefox and IE will run javascript in the background tabs, so there's no surefire way by simple polling to tell if the user is actually "looking" at the page or just has it open somewhere. Although I know of no way to tell if the user is actually looking at your page, a potential solution might be to bind polling to actions. So you might have some variable
var timesincelastaction=0;
var threshhold = 20;
Then
setInterval("timesincelastaction++",100);
Then
function keepAlive() {
if(timesincelastaction > threshhold) {
$.ajax(...tell the server you are alive...);
timesincelastaction = 0;
}
}
Then start thinking of actions like
$('a').mouseover(keepAlive);
$('div').mouseover(keepAlive);
$(window).scroll(keepAlive);
$(video).play(keepAlive); // okay this isn't a real one but you get the picture
So then you just brainstorm on everything the user can possibly be doing on the page that requires their attention and use those as your benchmark.
This seems a little intense I know, there's probably some nice ways to optimize it. Just thinking out loud. Curious to see what others come up with.
Every time one of your PHP scripts run, some user or entity has requested to view a page on your site (this usually occurs every time your script runs).
It is more challenging to detect when a user has left your page, which is why most online indicators are simply a timeout, i.e. if you have not been active on the website in the past 5 minutes, you are no longer considered online.
You can get information about the user who requested the page with variables like $_SERVER['REMOTE_ADDR'] or if you already have an authentication system you should be able to pull a users username, store this info in a database with the username/ip as a unique key with a timestamp, and simply not count them as online if their timestamp is older than 5 minutes.
You could probably use jQuery- ajax, unload and load. The ajax request will trigger on load telling you that they are viewing, and trigger on unload telling you they are no longer viewing. The rest is left to you to figure out because it sounds like you already have a grip on it.
Note. same result should be achievable in plain JS. Such as, onunload. Google will find you the rest.

Designing a "pop-out" interface that automatically updates - even possible?

So I developed this web application, which has several multiple select boxes on an admin page - each of these boxes contains multiple values, which we will call criteria.
The criteria in these boxes are generated on a form on another page and stored separately in another table in the database. The big problem is that my boss wants to have a new criteria editing page pop out in a new window, or a different tab of the same browser, allow the user to add one or multiple criteria, and have these update in the main admin browser window in real-time.
Now, if it was in the same window, my immediate thoughts would go to AJAX. However, because it will be in two separate browser windows, I don't believe this is a feasible solution.
Is there anyway (other than some form of COM programming or other OS-y methods, which I don't want to get into) to pass a value between the two browser windows, without having to reload the main page? That is a critical issue here - the main page cannot be reloaded at all during this process.
Would frames be the answer (thus getting rid of the dual browser window problem by not having two windows)? Something else? This is beyond my range of experience.
Possible solutions:
Frames (probably the simplest, works with old browsers too)
Comet (emulated JavaScript push notifications)
Mootools Request.Periodical
HTML5 Web Sockets (the "best" but works only in the newest browsers)
Well, you might be able to look into fsockopen() and see if a php socket solution could be useful in this case, but that may not be necessary since the skill level of sockets is - in my opinion - considerably higher than running a basic ajax request in your new frame to check if the form has changed within the last 5 seconds.
You can create a table in a database to represent a user's form and store the current values in that table along side a token that regenerates on each update. That way when you pop up your new screen that is supposed to live update you also send the form id and the first token. Then that window makes a basic ajax call every 5 seconds to see if the token for that form id has changed since the last call. If so, return a json object with all the info you need and update accordingly. If not, return false and do nothing.
This is just one possibility. It might be a lot of unnecessary db calls but then again - I don't know the purpose of this request so I don't know how absurd this solution is relative to your needs.
I stumbled across a usage of the localstorage (DOM storage) API for sharing messages across windows. I don't know how much data you need to send, and there are some compatibility concerns (support in IE starts in IE8, other browsers have good support for some versions now). Basically, each page would have an "onstorage" event handler set, so that a modification to a store (add, delete, modify/update) in one window would trigger the event in the other window as well. Of course, this is limited to the same origin. From how you described what you need, this sounds like it might be a valid solution.
Once you open a window using
var new_window = window.open(...);
then new_window is a reference to the window object in the new window, and from the new window window.opener is a reference to the window object in the original window. Subject to the same-domain security policy you'll be able to call functions "across the divide"

Refresh content automatically if the database changes

how can I automatically add the value of a database row (PHP), to the page, without refreshing the page itself, when the mysql database table changes?
So, it is a bit like this: Automatically refresh browser in response to file system changes? , but instead of refreshing the browser with the file system changes, update the content, without refreshing anything, when the databse changes.
Thanks. I have tried to make this as clear as possible.
Please note this is outdated answer. Recent ways of doing that is: websockets, server-send events. Nice example of that is Firebase. You can find simple code example in: https://github.com/laithshadeed/wsk-feedback. In this example you will see that updating firebase will send event to the browser via websocket, then the UI will update.
This is called Comet/Reverse Ajax/HTTP server push http://en.wikipedia.org/wiki/Comet_(programming). They are many techniques for doing this as well as many existing frameworks to do it for you.
There are many answers in SO about Comet https://stackoverflow.com/search?q=comet
Simple implementation would be javascript setTimeout and setInterval to check server status, with trigger/stored procedure on mysql.
For depth dive into Comet. There are two cool books about this:
Comet and Reverse Ajax 2008 By Dave Crane
Chapter 4 (River of Content) - Building the Realtime User Experience 2010 By Ted Roden
Update: You may look to the newer techniques in HTML5 like Websockets and Server-sent Events, although IE does not support them well, at the moment Server-sent events is not supported in IE and Web Sockets only supported in IE10
It's not a truly simple task, but it's not that bad. You need a few things working in concert:
A javascript routine on your page that checks with the server at specifiedintervals
A page on your server that reports changes when polled
A callback function on your page that inserts new elements (or updates/deletes existing elements) when changed data is reported by the server.
How you determine which data has been changed is something you will have to think about. The easiest way is probably to have a "modified" field maintained for each record. This way when your javascript polls the server it can include a "last time I checked" timestamp and the server only has to return changes that are more recent.
It's not quite so hard as it may at first appear. Take advantage of prebuilt libraries like jQuery and you can do things like:
$.ajax({
url: 'http://example.com/checkforupdates.php?last=' + (new Date().getTime()),
context: document.body,
success: function(data){
// do something here to add/update/remove elements on your page
// using the information returned in the data argument.
}
});
Manipulate the DOM with JavaScript.

CouchDB real-time Ajax push update

I'm working on a simple PHP application, using CouchDB and PHP-on-Couch to access some views, and it's working great. My next step is to introduce Ajax to update the frontend with data from the database.
I understand you can use the _changes notifications to detect any changes made on the database easily enough. So, its a matter of index.html monitoring for changes (through long polling), which calls loadView.php to update the page content.
Firstly, I hope the above is the correct method of going about it...
Secondly, when browsing to index.html, the page seems to never fully load (page load bar never completes). When a change is made, Firebug shows a the results as expected, but not any subsequent changes. At this time, the page seems to have stopped the infinite loading.
So far, i'm using jQuery to make the Ajax call...
$.getJSON('http://localhost:5984/db?callback=?', function(db) {
console.log(db.update_seq);
$.getJSON('http://localhost:5984/db/_changes?since='+db.update_seq+'&feed=continuous&callback=?', function(changes) {
console.log(changes);
});
});
Any ideas what could be happening here?
I believe the answer is simple enough.
A longpoll query is AJAX, guaranteed to respond only once, like fetching HTML or an image. It may take a little while to respond while it waits for a change; or it may reply immediately if changes have already happened.
A continuous query is COMET. It will never "finish" the HTTP reply, it will keep the connection open forever (except for errors, crashes, etc). Every time a change happens, zoom, Couch sends it to you.
So in other words, try changing feed=longpoll to feed=continuous and see if that solves it.
For background, I suggest the CouchDB Definitive Guide on change notifications and of course the excellent Couchbase Single Server changes API documentation.

I need an example of comet refresh html when database is updated!

People,
I am developing a web page that need to be refresh everytime that the data base gets an update. I already have the checkDatabaseUpdate() done in my PHP code.
But now I reaaly need some help to develop a simple comet to wait for a response, and another to check for update.
Is there anybody with any simple example to help me?
Is comet the right solution for that?
Thanks,
What you want to say is that on the database are executed querys (INSERT, UPDATE, DELETE) in the backend and you want to refresh the front page of a user when that query`s are executed ?
Hmm .. use a jQuery (looping) to "Ajax check" for database update in the frontcontroller and then refresh.
function refreshPage () {
$.load('checkModifDb.php', function(response, status) {
if .... { do the trick here - check jquery load.api }
}
});
and then use setInterval( "refreshPage()", 10000 ); to run the function every 10 seconds and
refresh only if it founds that db was modified.
I can't think of anything right now but i guess with little modification you shoul do the trick. This is how twitter.com do it.
Is comet the right solution for that?
Because of the way that PHP works (having a web server daemon process incoming requests), combining it with long-polling techniques can make for an unhappy server. Each connected user is going to hold open a connection to the web server daemon. Depending on that daemon's configuration, you may find that comet is an effective denial of service attack against your own server.
You'd probably be better off with plain old short-lived ajax polling here.

Categories