我按照一些教程从头开始创建机器人,基本功能正常工作,比如我可以连接,它响应命令,并输出到网页。
我想要的是周期性发送消息,其中包含我从某个卷曲网站获得的频道更新。
$ irc和$ curl只是带有设置的数组,而date('s')就是说返回更新的函数。当然我有工作卷曲功能。 $ irc ['delay']设置为10,所以在sleep(1)中它应该每10秒发送一次更新。
问题是,在第一分钟左右,它每隔10秒发送一次当前秒数,但它不会监听我设置的任何命令。它在第一次初始延迟之后执行命令,我不是它来自的地方 然后,只有当有人在频道上讲话时,它才会发出当前秒数(if条件)。我猜它等待这128个字节?但它确实会立即收听命令。
while(1) {
while($data = fgets($socket, 128)) {
echo nl2br($data);
flush();
if ($curl['delay'] <= $d) { fputs($socket, "PRIVMSG ".$irc['channel']." :".date('s')."\n"); $d=0; };
$d+=1;
sleep(1);
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
switch ($command) {
case ":!say" : fputs($socket, "PRIVMSG ".$ex[2]." :Hello!\n"); break;
case ":!off" : break 3;
};
};
}
我希望它能够响应命令,并定期自动发送拉取数据。但是我不明白它的行为,甚至不确定我想要的是什么可能再用php了
像Ranty建议的那样 没有休息: 它会说出一次日期,然后下次报告至少需要一分钟。如果我说任何命令它会进一步延迟它。
10:39 Moninal我来了
10:39 Moninal 39:24
10:40 Moninal 40:26
10:41 Moninal我来了
10:41 Moninal 41:05
10:41格雷戈斯!说出来
10:41 Moninal你好!
10:41格雷戈斯!说出来
10:41 Moninal你好!
10:42 Moninal 42:51
发送第二条消息后,我第一次在网页上输出,每隔61秒发送一次,而不是10秒。
10:42 Moninal 42:51
10:43 Moninal 43:52
10:44 Moninal 44:53
如果我在内循环中添加break: 对于第一分钟,我每10秒钟收到一次报告,但是在第一分钟结束时所有发送的命令都像以前一样触发。 在那之后命令工作,但每61秒再次报告。
也许这与我的服务器配置有关?
答案 0 :(得分:0)
我想问题是你在while($data = fgets($socket, 128))
循环中拥有所有逻辑。如果您考虑一下,如果聊天中发生了某些事情,您的逻辑就会被执行。所以当你启动脚本时,它执行正常,因为它读取那里的数据(我假设如此),但是在读取数据之后,它只对新数据执行。
现在它只在聊天时打印秒数,因为它等待128个字节的10倍(你的意思是10秒),因为只有当内部while循环条件总是为真时它才会是10秒(如果它每次执行都是秒)。
您可以尝试将一些逻辑移到内部while循环之外。我也为你改变了卷曲时间 - 你让它睡了1秒然后加1到柜台 - 这是不可靠的。您可以简单地比较上次请求的当前时间。
while(1) {
flush();
if ($curl['next_request'] <= time()) {
fputs($socket, "PRIVMSG ".$irc['channel']." :".date('s')."\n");
$curl['next_request'] = time() + $curl['delay'];
};
while($data = fgets($socket, 128)) {
echo nl2br($data);
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
switch ($command) {
case ":!say" : fputs($socket, "PRIVMSG ".$ex[2]." :Hello!\n"); break;
case ":!off" : break 3;
};
};
sleep(1);
}
它可能会同时响应所有命令,而不是每秒1次,如果你想改变它,你可以尝试在内部结束时添加一个中断。
答案 1 :(得分:0)
在经历了一天的痛苦之后,我终于找到了愚蠢的理由和解决方案。基本上1分钟延迟的原因是fget命令while($ data = fgets($ socket,128));
解决方法是设置stream_set_timeout($ socket,1);在循环之前。好吧我也最终设置了nginx服务器而不是apache。我不确定这无论如何都有帮助。
另外我想我可以在stream_set_timeout($ socket,1)中设置时间;控制发送消息的最小间隔。
$next=time();
stream_set_timeout($socket,1);
while(1) {
$data = fgets($socket, 128);
echo nl2br($data);
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
if (isset($ex[3])) $command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
switch ($command) {
case ":!sayit" :
$msg = NULL; for ($i = 4; $i < count($ex); $i++) { $msg .= $ex[$i] . ' '; }
fputs($socket, "PRIVMSG ".$ex[2]." :".$msg."\n");
break;
case ":!off" :
fputs($socket, "PRIVMSG ".$irc['channel']." : Bye\n");
fputs($socket,"QUIT Client Disconnected!\n");
die('Exited!');
};
if ($next <= time()) {
fputs($socket, "PRIVMSG ".$irc['channel']." :".date('H:i:s')."\n");
echo "PRIVMSG ".$irc['channel']." :".date('H:i:s')."<br />";
$next = time() + $curl['delay'];
};
flush();
};
好吧,它不包括所有连接设置。这很容易找到怎么做。