0

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.

Andrew Latham
  • 5,982
  • 14
  • 47
  • 87

5 Answers5

2

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.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • +1 for finding that stackoverflow question which has this very relevant link: http://www.thefutureoftheweb.com/blog/detect-browser-window-focus – clumsyfingers Aug 03 '12 at 00:38
1

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.

Tim Withers
  • 12,072
  • 5
  • 43
  • 67
1

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.

clumsyfingers
  • 485
  • 4
  • 10
0

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.

mash
  • 14,851
  • 3
  • 30
  • 33
0

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.

Kurt
  • 7,102
  • 2
  • 19
  • 16