我遵循一些教程从头开始创建bot,基本功能工作良好,就像我可以连接一样,它响应命令,并输出到网页。
我想要的是周期性地发送消息与更新到频道,我从一些网站curl。
$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]电影我来了
[10:39]梦剧场39:24
[10:40]电影40:26
[10:41]电影《我来了》
[10:41]电影41:05
[10:41]格雷戈斯,说出来
[10:41]莫妮卡:你好!
[10:41]格雷戈斯,说出来
[10:41]莫妮卡:你好!
[10:42]梦剧场42:51
在它发送第二条消息后,我第一次在网页上得到输出,并且每隔61秒发送一次下一个报告,而不是10秒。
[10:42]梦剧场42:51
[10:43]电影43:52
[10:44]电影44:53
也许是我的服务器配置有问题?
我猜问题是你在while($data = fgets($socket, 128))
循环内拥有所有逻辑。如果你想一下,你的逻辑被执行,如果有一些在聊天发生。因此,当您启动脚本时,它执行正常,因为它读取了那里的数据(我假设是这样),但在读取数据之后,它只对新数据执行。
现在它只在chat上打印秒数,因为它等待了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);
}
它可能会同时响应所有命令,而不是每秒一个,如果你想改变这一点,你可以尝试在内部while的末尾添加一个break。
好了,经过一天的痛苦,我终于找到了愚蠢的原因和解决办法。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();
};
它不包括所有的连接设置。