0

Is there a simple and efficient way to get the number of visitors who have a given web page open?

The ultimate goal is to do this:

  1. Check how many visitors there are on the page, i.e. who have the page open in their browser.
  2. If it exceeds a certain number n, display a button. The first x visitors who press the button would go to a different page.
  3. As long as there are more than n visitors, the button will keep displaying. If not, the button disappears.

Any trick for doing this? Long-polling? Websocket? The simpler the better.

skyork
  • 7,113
  • 18
  • 63
  • 103
  • This type of functionality is known as user presence. At Pusher we have [presence channels](http://pusher.com/docs/presence_channels) but other realtime web technologies may offer presence functionality in other ways. – leggetter Oct 09 '12 at 12:54

3 Answers3

2

This task can be easily done using WebSockets. Below there is required application code written using Bristleback Server (assuming that the check is performed when new user is connecting).

@Component
public class CountUsersConnectionListeners implements ConnectionStateListener<DefaultUser> {

  private static final int MAGIC_MAXIMUM_NUMBER_OF_USERS = 2;

  private int numberOfCurrentlyConnected;

  @Autowired
  private ConnectionCountClientClass connectionCountClientClass;

  @Override
  public void userConnected(DefaultUser defaultUser) {
    if (numberOfCurrentlyConnected > MAGIC_MAXIMUM_NUMBER_OF_USERS) {
      connectionCountClientClass.showButtonToNewUser(defaultUser);
      numberOfCurrentlyConnected++;
      return;
    }

    numberOfCurrentlyConnected++;
    if (numberOfCurrentlyConnected > MAGIC_MAXIMUM_NUMBER_OF_USERS) {
      connectionCountClientClass.showButton(true);
    }
  }

  @Override
  public void userDisconnected(DefaultUser defaultUser) {
    if (numberOfCurrentlyConnected <= MAGIC_MAXIMUM_NUMBER_OF_USERS) {
      numberOfCurrentlyConnected--;
      return;
    }

    numberOfCurrentlyConnected--;
    if (numberOfCurrentlyConnected <= MAGIC_MAXIMUM_NUMBER_OF_USERS) {
      connectionCountClientClass.hideButton(true);
    }
  }
}

Note that this is just a prototype, I did not care about synchronization and the code where actual number of connected users is set could be placed elsewhere.


@ClientActionClass
@Component
public class ConnectionCountClientClass {

  @ClientAction
  public SendCondition showButton(boolean show) {
    return AllUsersCondition.getInstance(); // this will send a message to all connected users
  }

  @ClientAction
  public SendCondition hideButton(boolean hide) {
    return AllUsersCondition.getInstance(); // this will send a message to all connected users
  }

  @ClientAction
  public DefaultUser showButtonToNewUser(DefaultUser defaultUser) {
    return defaultUser; // this will send a message only to the user given as parameter
  }
}

Client side (only additional application code presented):

var sampleClientAction = {
  showButton: function() {
    alert("Show button!");
  },
  showButtonToNewUser: function() {
    alert("Show me button!");
  },
  hideButton: function() {
    alert("Hide button!");
  }
};

dataController.registerClientActionClass("ConnectionCountClientClass", sampleClientAction);

If you're interested, I can send you entire working application [Maven required]. Jetty or Tomcat can be used as web application containers.

voitec
  • 133
  • 5
1

Well you could either use Websocket's like you have mentioned or just simple AJAX to poll the server every 100ms, and until the Websocket hasn't been closed or until the server didn't get a response from the browser for 500ms then the user is "connected" using AJAX.

And just add all those users which are connected to a page to a database based on their page and distinct ip's on a page, and count them once there are n entries on a specific page return a response to all browsers to show the button.

And if there are less than n just send a response to hide the button.

Shedokan
  • 1,212
  • 1
  • 10
  • 21
-1

your site is static then use

http://www.kavoir.com/2010/05/simplest-php-hit-counter-or-download-counter-count-the-number-of-times-of-access-visits-or-downloads.html

if your site is dynamic then save counter in your database with page name

Dhaval Dhami
  • 75
  • 1
  • 8
  • I don't think this is what I want. I need to know the number of users who *currently have a particular page open*, not the number of users who *have visited* the page. – skyork Oct 08 '12 at 13:19