English 中文(简体)
How to make all connected browsers reload initiated by a server-side event
原标题:

Suppose there is a webpage with dynamically generated content -- say a div containing the current number of connected browsers. When the count changes on the server I want all connected browsers to reload the count so that everyone sees the increment/decrement.

What s the best way to accomplish this?

Keywords: ajax, broadcast, browser, div, jquery

最佳回答

Here s how to do server-push using ajax long-polling. The browser makes an ajax request which initiates server-side self-polling. The ajax request remains open, waiting for a response until the file changes, and as soon as it gets a response, it makes a new long-polling request.

Here s what it looks like with jQuery and php, implementing the example of live-updating a div in the html showing the number of clients currently connected:

index.html:

<html>
<head>
<title>Comet Test</title>
  <script type="text/javascript" src="jquery.js"></script>
  <script type="text/javascript" src="longpolling.js"></script>
</head>
<body>
  Number of connected users: <div id="total">0</div>
</body>
</html>

longpolling.js:

$(document).ready(function() { connectToServer(1); });

function connectToServer( incp ) {
  $.get("LongPolling.php",
        { inc: incp },
        function(resp) {
          $( #total ).html(resp);
          connectToServer(0);
        }
       );
}

LongPolling.php:

<?php

# (over)write file with contents, locking the file while doing so.
# just barf and die if there s an error.
function update($file, $contents)
{
  $f = fopen($file,  w );
  if(!$f) { echo "ERROR1"; exit; } # couldn t open file for writing.
  if(!flock($f, LOCK_EX)) { echo "ERROR2"; exit; } # couldn t get lock.
  fwrite($f, $contents);
  fclose($f);  # this also releases the lock.
  return $contents;
}

# fetch the contents of the given file.
# if the file doesn t exist, create it with contents "0"
function fetch($file)
{
  if(file_exists($file)) {
    if(!is_readable($file)) { echo "ERROR3"; exit; }
    $x = file_get_contents($file);
  } else {
    $x = 0;
    update($file, $x);
  }
  return $x;
}

$fc =  connx.txt ;   # file that stores the number of connections.

if ( $_REQUEST[ inc ] == 1 ) {  # someone just connected.
  echo update($fc, fetch($fc)+1);
} else {  # someone is reconnecting (also happens immediately after connect).
  $last = filemtime($fc);
  do {  # wait until some other instance causes $fc to change...
    sleep(1);
    clearstatcache(); # otherwise filemtime() results are cached!
  } while(filemtime($fc) == $last);
  echo fetch($fc);
}
?>

NOTE: This does not track disconnects, so it s more like live-tracking the total number of pageviews. See Running server-side function as browser closes for info on keeping track of browser disconnects, ie, server-side action on client disconnect.

问题回答

I think COMET might be what you re looking for. Web Sockets would be ideal but lack of browser adoption wouldn t make it practical right now.

HTTP protocol is stateless by design. The only one way to achieve this is to implement client-side polling via AJAX.

Reverse AJAX is what you need. It s briefly explained in the DWR web page: http://directwebremoting.org/dwr/reverse-ajax/index.html - you can probably use one of the three flavours with the library you are using for ajax calls.

As of Dec 2014, there is a W3C proposed recommendation called Server Sent Events (SSE) that would allow you to do that over HTTP: http://www.w3.org/TR/eventsource

It seems that it is a standardization of a group of techniques known as Comet. (which Darrel linked to in his answer)

A full example from 2013 with Sinatra can be found at: http://html5hacks.com/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/

There is also a 2010 HTML5 Rocks article: http://www.html5rocks.com/en/tutorials/eventsource/basics/ , but the spec is likely t have changed a bit since.

Most current browsers support this API, with the notable exception of IE11: http://caniuse.com/#feat=eventsource

it is possible to write a java applet which can work as a network server. Once the applet has successfully started, it can report its port and ip number back to the remote server.

Then your server can send messages to the client server any time it feels like. Your java applet can then hand the message off to javascript, or do whatever else.

This method requires java plugin support however, which is far from universal.





相关问题
ajax login using httpRequest?

I am trying to develop my login script to give feedback to the user if the login is valid or not. Basically if it isn t correct a div box will show saying its wrong, if its correct it will show its ...

Virtual Tour using sketch up, ajax, flash technologies

I want to know if there are existing technology that make your 3d models in sketch into virtual tours, using either Ajax or Flash for web presentation. If there s none, which will be a good approach ...

How can i update div continuously

I have asp.net application where i have a div which showing the value from other site. The value of that site is changing continuously. I want that my div will automatically update in some interval ...

热门标签