4

假设有一个动态生成内容的网页——比如一个包含当前连接浏览器数量的 div。当服务器上的计数发生变化时,我希望所有连接的浏览器重新加载计数,以便每个人都能看到增量/减量。

实现这一目标的最佳方法是什么?

关键词:ajax、广播、浏览器、div、jquery

4

7 回答 7

7

我认为COMET可能是您正在寻找的。 Web Sockets将是理想的,但缺乏浏览器采用不会使其现在变得实用。

于 2009-12-26T22:11:29.803 回答
5

HTTP 协议在设计上是无状态的。实现这一点的唯一方法是通过 AJAX 实现客户端轮询。

于 2009-12-26T22:10:44.833 回答
3

这是使用 ajax 长轮询执行服务器推送的方法。浏览器发出 ajax 请求,启动服务器端自轮询。ajax 请求保持打开状态,等待响应,直到文件更改,一旦得到响应,它就会发出新的长轮询请求。

这是jQuery和 php的样子,实现了在 html 中实时更新 div 的示例,显示当前连接的客户端数量:

索引.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);
        }
       );
}

长轮询.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);
}
?>

注意:这不会跟踪断开连接,因此它更像是实时跟踪总浏览量。有关跟踪浏览器断开连接的信息,请参阅在浏览器关闭时运行服务器端功能,即客户端断开连接时的服务器端操作。

于 2010-01-04T21:25:01.193 回答
1

小推车

于 2009-12-26T22:13:45.303 回答
0

反向 AJAX 是您所需要的。在 DWR 网页中对其进行了简要说明:http: //directwebremoting.org/dwr/reverse-ajax/index.html - 您可以将这三种风格中的一种与用于 ajax 调用的库一起使用。

于 2009-12-26T23:22:59.487 回答
0

截至 2014 年 12 月,W3C 提出了一项名为服务器发送事件 (SSE) 的建议,允许您通过 HTTP 执行此操作:http: //www.w3.org/TR/eventsource

它似乎是一组被称为 Comet的技术的标准化。(达雷尔在他的回答中链接到)

2013 年使用 Sinatra 的完整示例可在以下位置找到: http: //html5hacks.com/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/

还有一篇 2010 年 HTML5 Rocks 文章:http ://www.html5rocks.com/en/tutorials/eventsource/basics/ ,但从那以后规范可能没有改变。

当前大多数浏览器都支持此 API,但 IE11 除外:http ://caniuse.com/#feat=eventsource

于 2014-12-10T16:06:44.750 回答
-1

可以编写一个可以用作网络服务器的 Java 小程序。一旦小程序成功启动,它可以将其端口和 ip 号报告回远程服务器。

然后,您的服务器可以随时向客户端服务器发送消息。然后,您的 java 小程序可以将消息传递给 javascript,或执行其他任何操作。

但是,此方法需要 java 插件支持,这远非通用。

于 2009-12-26T23:12:22.130 回答