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.
Related
I was working on a web app and thought it would be awesome to give the user a tooltip or side note on a new feature that has been added.
This would be similar to the way Google or Facebook displays their tips about updates.
I had an idea of setting a cookie (or session variable) to say that the tip has been viewed and not display it again, but this would be running an unnecessary if statement on every page load.
Here is what I have so far:
if ($_COOKIE['displayTip'] != 'no') {
echo "tip";
}
Are there better ways of doing this, or is one if every page load worth it?
A single if - especially if it is not checking a database - is no problem. Don't worry about it, you can waste more CPU time with other things. If it adds functionality its fine.
One thing you could do is to have the logic on in the Browser (JavaScript) only. This has the advantage you do not have to generate two different pages. This might be beneficial for caching. In JS you can also access cookies to make that seen flag persistent.
I have a PHP page with a simple form. One input text field & a button. Input text field accepts user queries & on button click an HTTP GET request is made to the server & the result has to be shown back in the same page containing the form. That's too simple to do. I can do this in two ways. One is AJAX & other one is the good old sodding form-submit method.
My question is simple- Which method should I use? Since both of the roads lead us to the same place, which one should I choose to travel?
First of all, let me talk about form submit method. I can use <?php echo $_SERVER['PHP_SELF'] ; ?> as the action of the form for submitting the values of my form to the same page. Once I store those values into some random variables, I can make a GET request & obtain the result & show it to the world. This method is easy to use. Happy Down Voting to all of you.
Or I can make a GET request using AJAX and jQuery or JavaScript or whatever you wish to use & obtain the same result as in the previous case. Output is same. Only the mode of execution is different.
So which one is better? Which one fetches result faster? And why should I use that? Is there any difference? GET, POST, PUT or whatever- it doesn't really matter. AJAX or form-submit?
There shouldn't be any significant, genuine speed difference between them.
The Ajax approach will load a smaller amount of data (since you aren't loading an entire HTML document), but by the time you take into account HTTP compression and the fact that (if your system is sensibly configured) your dependancies (images, scripts, stylesheets, etc) will be cached, it won't be significantly smaller.
By using JavaScript to create a loading indicator and not refreshing the entire window in front of the user, you can create the illusion of a faster load time though. So if feeling faster was the only concern, then Ajax is the way forward.
Using JavaScript, however, is more complicated and slightly more prone to failure. The consequences of failure states are more severe because, unless your code detects and does something with them, the user will (not) see it fail silently. For example, if a normal page load times out because the user is on a train and went through a tunnel, they'll see an error page provided by their browser suggesting that they refresh and try again. With Ajax, you need to write the error handling code yourself. This does give you more flexibility (such as allowing you to simply try again a few times) but the work isn't done for you.
The other consequence of using Ajax is that the address bar will not update automatically. This means that the results won't be bookmarkable or sharable unless you do something explicit the make that possible. The usual way to do that is pushState and friends, but again, it is more work.
You should also make the site work without JavaScript so that if the JS doesn't run for any reason then the site won't break completely. If you use pushState then you have to do this for the URLs you are setting the address bar to point to to be useful.
The short answer: Use a regular form submission, then consider layering JavaScript over the top if you think it will give your visitors a worthwhile benefit.
I Should stick to an Ajax request when possible.
This because you then don't really have to load every single item on the page again ( like all the images, menu and so on ). You can just give the relevant HTML back and JQuery can place it inside the relevant holder.
But that is just my humble opinion...
If you have to retrive simple data from server without reload the page my advice is use jquery .get o .post
also it provides you a very large API that allows you to reduce your programming time.
http://api.jquery.com/
obviously the execution time increase but in my experience the user cant fell the differce with a simple ajax request.
so in my opinion if jquery allow you to obtain the results, this is the best solution because halves your work time!
See the edited one it may help you.
I think that AJAX should be used for displays updates and form submissions should be done via a page reload. Reasoning?
When submitting forms, you are telling the application to do something. Users tend to want to feel that it was done. When a page doesn't reload, users are often left wondering "Did that work?". Then they have to check to make sure what they did was right.
but when you are displaying a table or something, and the user says to "display x data....now x1 data" for instance, they aren't "doing" something (creating new entities, sending emails, etc). So AJAX can provide a nice user interface in this case. Page reloads would be annoying here.
In conclusion, I think form submission should be done via page reloads (let the user see it working), whereas display updates should use AJAX (prevent annoying page reloads).
Of course, this is a preference thing. Some of my company's applications use AJAX all over. But those are the applications that are the most difficult to maintain and debug. ;)``
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"
I am currently planning a web based application, which needs to do long calculations on the server upon request. Now I would like to display a notification to the user, that the calculation is in progress, and then redirect that page as soon as the calculation is done.
There is no need to notify the user of the progress or display a progress bar, I simply want to exchange the site as soon as the calculation is done.
I am trying to stay clear of any additional webkits besides plain javascript, so this solution is much to complicated.
One idea I have is to just start a http query from javascript in the waiting page and not return anything on the server side until the calculation is done. This way I would keep the query blocked until the connection is finished. Once it is done, I return something and close the connection, so the blocked call can continue and redirect the user. However I am afraid that this might give me a timeout on the network if there is nothing going through that connection.
How is something like this normally handled?
The way this is normally handled is doing periodic calls to a page that returns the progress. The simplest way it running an ajax call ever X seconds that returns 0 when not complete and 1 when complete.
Basically you should just poll the server for a status update on the job and do nothing until it returns 1
I would go for ChrisR's solution.
And while the user is waiting for the process to complete, you can display a spinner (as Greg said) but I would go for a fancier solution rather than an animated gif :)
May I suggest to try the Heartcode CanvasLoader?
http://heartcode.robertpataki.com/canvasloader/
Good luck,
Rob
Why not just use a spinner image? http://www.iconfinder.com/search/?q=spinner
On one of my pages I have users queue up search terms to be to queried from a 3rd party API. As they're building the queue, my site is making the queries in the background (through ajax) so I can cache the responses, saving them time when they submit. I store a session variable $_SESSION['isloading'] as true during the time that the background queries are running, and its false when they're done.
When they submit, the results page waits for $_SESSION['isloading'] to be false before querying the cache for result. Meanwhile they're shown a progress wheel.
Is there a name for this technique of using a session to locally "lock" a user before proceeding to the next step in the code? I came up with this approach on my own and was wondering if it is a common (or good) solution to this problem, and is used elsewhere.
Putting it in $_SESSION will be a wasted effort. Been there, done that and it didn't work out.
You will be much better off if you provide your "search query string" in as a $_GET variable for your XHR ( marketing people call it - Ajax ).
Off the top of my head, this sounds a little similar to the way some older forum software performs forum searches in the background, and the visible page does a repeated refresh until the background search is complete.
I don't think there's a name for it; I'm also note entirely convinced that it's a great solution. As stevecomrie pointed out, you're going to run into difficulties with concurrency (unless the session variable's name is unique per search query).
I'd instead recommend an XmlHttpRequest (as teresko points out, it's not really called "AJAX", ugh!) and you can handle the "waiting" quite simply with Javascript.
I asked about this on IRC (Hat-Tip to ##php on freenode), and they suggested I just make the search form and search results one page. Then, when they're done entering their searches the view would change rather than submitting to the next page. This would remove the necessity of keeping track of an 'isloading' state. This seems like a better approach to me, are there any problems with it?