2010-11-19 156 views
1

我遇到了IRC Bot脚本的问题,我已将它实现到了我的Curl转移方法中。PHP - IRC Bot脚本挂起

我有一个问题,一旦IRC机器人向IRC频道发送消息,脚本末尾的所有“回显”都不会显示,并且页面挂起。整个Apache挂起。

<?php 

$ircServer = "///"; 
$ircPort = "6667"; 
$ircChannel = "#bots"; 

set_time_limit(0); 

$msg = $_POST['msg']; 
$paper = $_POST['paper']; 
$sizzor = $_POST['sizzor']; 
$hand = $_POST['hand']; 

$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS); 

if ($ircSocket) 
{ 

    fwrite($ircSocket, "USER Lost rawr.test lol :code\n"); 
    fwrite($ircSocket, "NICK Rawr" . rand() . "\n"); 
    fwrite($ircSocket, "JOIN " . $ircChannel . "\n"); 

ignore_user_abort(TRUE); // Noob Close down page 

    fwrite($ircSocket, "PRIVMSG " . $ircChannel . " :" . $msg . "\n"); 

    while(1) 
    { 
     while($data = fgets($ircSocket, 128)) 
     { 
      echo nl2br($data); 
      flush(); 

      // Separate all data 
      $exData = explode(' ', $data); 

      // Send PONG back to the server 
      if($exData[0] == "PING") 
      { 
       fwrite($ircSocket, "PONG ".$exData[1]."\n"); 
      } 
} 
    echo $eS . ": " . $eN; 
} 
} 
?> 
if ($bootcontents == 'success') {  
echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

这部分不脚本中显示:

if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 

页面只是挂起,如果我添加了exit();功能上接近顶部整个“回声”信息不显示。

请有人帮忙。

+0

我看到你有一个循环:while(1)。如果你没有终止条件来打破这个循环,它将是一个无限循环。 – ryanlahue 2010-11-19 22:39:25

+3

通过网络服务器启动这样的东西是不好的。此外,理智的服务器不会让你的机器人发送任何消息,因为它不响应可能在收到USER和NICK后立即发送的PING。 – ThiefMaster 2010-11-19 22:43:52

+0

您必须从命令行运行您的bot,而不是通过网页。 – Jocelyn 2012-06-05 21:37:47

回答

0

你正在创建一个无限循环:

while (1) 
// ... 

这个循环可以写不完,因为你没有使用EXIT指令(如break)。因此无限循环后的代码永远不会执行。 此外,它是一个繁忙的循环(使用大量的CPU资源),所以整个Apache(和计算机)将挂起。

+0

为什么是-1?答案应该是正确的(?) – apfelbox 2012-08-06 23:03:56

+0

该脚本旨在无限运行,即通过设计。可能这就是为什么你会看到downvote。从代码中可以明显看出这是有意的。当然,给出的解释是OP失败的一部分。所以你得到反对票。 – hakre 2012-08-13 11:03:08

+0

hakre ... OP的目的是要有一个无限循环来捕捉服务器输出,但他的设计是完全错误的......并回答OP为什么回声从未运行与上述2回复的问题完全有效,因为他从来没有问过关于他的设计,但为什么这部分代码不起作用。所以我们可以忽略他的设计意图,并对代码本身发表评论。 – Populus 2012-10-14 23:48:28

0

您正在从<?php ?>标记中删除一些标记,因此无论外界的标记都将被视为纯文本。你修复它移动结束?>标签进一步下跌:

 [this is the while(1) closing bracket] 
     } 
    // code past this line will never run, see below for details 
    echo $eS . ": " . $eN; 
    } 
} 
if ($bootcontents == 'success') { 
    echo '<center><marquee behavior="alternate" direction="left">Spinning xxx at ' . $power . '% power.</marquee></center>'; 
} 
?> <!-- closing tag goes here --> 

该网页将反正不能正确,因为while(1)环缺少退出条件工作

while(1) { 
    while($data = fgets($ircSocket, 128)) { 
     // ... 
    } 
} 

while完成后,你的脚本不断循环,最终陷入一个空的无限循环(如果它没有配置为检测并消除这种漏洞,它将挂起服务器)。

在最后的通知中,PHP并不是最适合这项工作的工具:使用独立应用程序可能会更好。

0
while($data = fgets($ircSocket, 128)) 

这部分阻止脚本运行,直到它接收到的数据,如果不知何故你不通过该套接字获取数据...好你被困在那里...永远...哈哈OK,卡住直到PHP脚本超时。

如果这部分没有捕获,你仍然被困在while循环中,所以没有办法运行你的代码的那部分回声消除......所以apfelbox和Alex都是正确的,只是没有完全解释...

为了有一个无限循环,但也能够在外面运行代码,你需要捕捉你想捕获和运行代码的“事件”。你想要捕获的所有事件都需要在while循环中,或者至少从while循环分派到一个函数,该函数可以解析来自服务器的输入并正确响应。

更好的方法是利用观察者模式。

即使通过命令行运行它,我也不会用PHP创建IRC bot。PHP并不意味着作为一个长期运行的应用程序运行。