我目前有一个用C++编写的IRC机器人程序,它监视用php编写的页面的更改,然后将这些更改输出到IRC通道。然而,目前的方法相当有效,因为它只是每10秒不断地轮询一次页面,并将其与上次看到的版本进行比较,以检查是否有任何变化。我可以在IRC机器人开始受到性能影响之前将页面检查间隔缩短到大约2-3秒,但这并不理想。通常,我监视的页面可能在10秒内发生多次更改,因此可能会错过更改,从页面中获取数据的更好方法是什么?考虑到我控制着用PHP编写的页面和IRC机器人,但它们在不同的服务器上。
这个页面的唯一目的是将数据传递给IRC机器人,因此如果这是一个更好的解决方案,它可以完全重新实现为其他东西;IRC机器人程序还监视该页面的多个版本,以检查不同的内容。
如果PHP生成的数据没有以某种方式在流(广播或提要)上推送,那么不幸的是,您除了轮询页面之外别无选择。
你可以做的是使用广播推送来自PHP的数据,或者从机器人程序到PHP脚本建立持久连接,或者让PHP自己计算差异。
PHP脚本应该向IRB机器人监听的公共端口或路径发送一条消息,其中包含有关任何帖子的信息。这样,只有当消息到达时才会通知您。
关于做这类事情的一个注意事项是,如果在短时间内有很多帖子,要小心;如果并发性很重要,您将希望使用适当的MQ服务(如0MQ/RabbitMQ/InsertMQFrameworkNameHere)来实现这一点,以确保消息按顺序到达,并保证发送和接收。
如果你需要监控每一个更改,那么让你的PHP页面"推送"数据到你的机器人,而不是让你的IRC机器人从页面"拉取"数据(通过轮询)。这可以通过任何网络套接字完成,甚至可以通过端口80从PHP页面向机器人发出HTTPPOST请求。
Comet是轮询的一个很好的替代方案。以下是示例(不过是针对JavaScript):http://www.zeitoun.net/articles/comet_and_php/start.
我建议采用这种方法:
-
当你检索页面时,指定一个很长的超时时间,比如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>