如何在不轮询的情况下监视页面的更改?
Posted
技术标签:
【中文标题】如何在不轮询的情况下监视页面的更改?【英文标题】:How to monitor page for changes without polling? 【发布时间】:2011-05-26 16:17:39 【问题描述】:我目前有一个用 C++ 编写的 IRC 机器人,它监视用 php 编写的页面的更改,然后将这些更改输出到 IRC 通道。 然而,当前的方法相当无效,因为它只是每 10 秒不断地轮询一次页面,并将其与上次看到的版本进行比较,以检查是否有任何变化。 在 IRC 机器人开始受到性能影响之前,我可以将页面检查间隔减少到大约 2-3 秒,但这并不理想。 通常我正在监视的页面可能会在 10 秒内多次更改,因此可能会错过更改,从页面获取数据的更好方法是什么?考虑到我控制用 PHP 编写的页面和 IRC 机器人,但它们位于不同的服务器上。
此页面的唯一目的是将数据传递给 IRC 机器人,因此如果这是一个更好的解决方案,它可以完全重新实现为其他东西; IRC 机器人还监视此页面的多个版本以检查不同的内容。
【问题讨论】:
【参考方案1】:如果 PHP 生成的数据没有以某种方式推送到流(广播或提要)上,那么很遗憾,除了轮询页面之外,您别无选择。
你可以做的是push使用广播从 PHP 中获取数据,或者建立从 bot 到 PHP 脚本的持久连接,或者让 PHP 自己计算差异。
【讨论】:
【参考方案2】:PHP 脚本应该向您的 IRB 机器人侦听的公共端口或路径发送一条消息,其中包含有关发布的任何帖子的信息。这样,只有在消息到达时才会通知您。
做这些事情的一个注意事项,注意短时间内是否有很多帖子;如果并发性很重要,您需要使用适当的 MQ 服务(如 0MQ/RabbitMQ/InsertMQFrameworkNameHere)来实现这一点,以确保消息按顺序到达并保证发送和接收。
【讨论】:
【参考方案3】:如果您需要监控每个更改,那么让您的 PHP 页面“推送”数据到您的机器人,而不是您的 IRC 机器人从页面“拉”数据(通过轮询)。这可以通过任何网络套接字完成,甚至可以通过端口 80 从 PHP 页面向机器人发出 HTTP POST 请求。
【讨论】:
【参考方案4】:Comet 是轮询的一个很好的替代方案。以下是示例(尽管适用于 javascript):http://www.zeitoun.net/articles/comet_and_php/start.
【讨论】:
【参考方案5】:我会建议这种方法:
当您检索页面时,指定一个很长的超时时间,比如 10 分钟(请耐心等待);
如果有新页面,让服务器返回;否则就不要回复了
如果没有页面,客户端最多会等待10分钟才放弃(超时);但是,如果在此期间有新页面,您的服务器可以回复请求并将页面传递给客户端;
如果超时触发,您只需发送另一个具有相同长超时的请求。
希望我能解释清楚。唯一棘手的一点是,如果没有新数据要发回,您的网页 (PHP) 如何在请求到达时保持等待。 这可以像这样轻松完成:
if ($newDataAvailable)
file_put_contents($data, $request_uri);
return;
while (!$newDataAvailable)
usleep(10000);
$newDataAvailable = <check_for_data>;
//-- here data is available
<build response using get_file_contents($uri)>
<send response>
【讨论】:
以上是关于如何在不轮询的情况下监视页面的更改?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不轮询内核的情况下监控 C 程序中的 NIC 状态(启动/关闭)?
如何让 GraphQL 在不进行轮询的情况下从数据库中获取实时/新数据?
有没有办法在不轮询 REST API 的情况下通知 Google AI Platform 训练作业的状态变化?
在 Perl 中,如何在没有轮询但有超时的情况下监视文件更改?