Stack Overflow的开发人员大家好!我最近重新开始进行Web开发(虽然我以前不太擅长),PHP是我的首选武器。自从我离开之后,PHP似乎已经发生了变化,并将其与我从未使用过PHP套接字这一事实相结合,然后导致了灾难性的第一次创建IRC机器人的尝试(我在IRC频道上,机器人开发很大,我想将它集成到我的网站。在php中编写它似乎也是一个有趣的挑战)。它创建了一个无限循环,使我的浏览器变慢,我无法复制任何错误或警告。好心人会这么想看这个脚本(基于这个bot):
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Lucky Cloud</title>
</head>
<body>
<?php
error_reporting(E_ERROR);
$bot = array(
"Host" => "irc.quakenet.org",
"Channels" => ["#cplusplus", "#BotDevGroundZero"],
"Nick" => "LuckyCloud",
"Ident" => "LuckyCloud",
"Real" => "LuckyCloud",
"Port" => 6667
);
$buffer = "";
?>
<p>
Server: <?php echo $bot["Host"]; ?><br />
Channel(s): <?php foreach($bot["Channels"] as $channel) echo $channel.($channel != end($bot["Channels"]) ? ", " : ""); ?><br />
Port: <? echo $bot["Port"]; ?><br />
___________________________________________________________________________________________________________________<br />
</p>
<?php
global $socket;
$socket = fsockopen($bot["host"], $bot["Port"]);
function sendData($cmd, $msg = null) {
if($msg == null) {
fputs($socket, $cmd."\r\n");
echo "<strong>".$cmd."</strong><br />";
}
else {
fputs($socket, $cmd." ".$msg."\r\n");
echo "<strong>".$cmd." ".$msg."</strong><br />";
}
}
sendData("NICK", $bot["Nick"]);
sendData("USER", $bot["Ident"]." ".$bot["Host"]." ".$bot["Real"]);
$buffer = "";
while(true) {
foreach($bot["Channels"] as $channel) {
sendData("JOIN", $channel);
}
$buffer += fgets($socket, 1024);
$temp = explode("\n", $buffer);
$buffer = end($temp);
foreach($temp as $line) {
echo $line;
$line = rtrim($line);
$line = explode($line);
if($line[0] == "PING") {
sendData("PONG", $line[1]);
}
}
}
?>
</body>
</html>
抱歉任何格式问题。 cpanel编辑器表现得很奇怪
答案 0 :(得分:2)
你无法以这种方式实现它,导致问题的原因很简单,一旦while(true)
循环启动它就不会停止。
您需要将请求与处理循环分开。所以将循环作为后台进程(守护进程),然后通过另一个接口(例如threads
数据库)将PINGS和PONGS等推送到它,然后在循环的每次迭代中,查询数据库中的PINGS和PONGS。
答案 1 :(得分:0)
PHP不是这项工作的最佳选择。保持长时间连接并不是很好。此脚本可能用于短时联接,您只需删除邮件并离开即可。类似“基于事件的通知”。
您的脚本的几个补充:
while (!feof($socket)) {
<html lang="en-US">
<head>
<title>Lucky Cloud</title>
</head>
<body>
<?php
date_default_timezone_set('America/Los_Angeles');
error_reporting(E_ALL);
ini_set("display_errors", 1);
set_time_limit(0);
$bot = array(
"Host" => "kornbluth.freenode.net", #"underworld2.no.quakenet.org", #irc.quakenet.org",
"Channels" => ["#testerchan"],
"Nick" => "Tester7888",
"Ident" => "Tester7888",
"Real" => "Susi Q",
"Port" => 6667
);
?>
<p>
Server: <?php echo $bot["Host"]; ?><br />
Channel(s): <?php foreach($bot["Channels"] as $key => $channel) { echo $channel; } ?><br />
Port: <?php echo $bot["Port"]; ?><br />
___________________________________________________________________________________________________________________<br />
</p>
<?php
global $socket;
function sendData($cmd, $msg = null) {
global $socket;
if($msg == null) {
fputs($socket, $cmd."\r\n");
echo "<strong>".$cmd."</strong><br />";
} else {
fputs($socket, $cmd." ".$msg."\r\n");
echo "<strong>".$cmd." ".$msg."</strong><br />";
}
}
$socket = fsockopen($bot["Host"], $bot["Port"], $error1, $error2);
if(!$socket) {
echo 'Crap! fsockopen failed. Details: ' . $error1 . ': ' . $error2;
}
sendData("NICK", $bot["Nick"]);
sendData("USER", $bot["Ident"]." ".$bot["Host"]." ".$bot["Real"]);
$join_at_start = true;
$buffer = "";
while (!feof($socket)) {
$buffer = trim(fgets($socket, 128));
echo date('H:i')." ".nl2br($buffer)."<br/>";
flush();
# Ping <-> Pong
if(substr($buffer, 0, 6) == "PING :") {
fputs($socket, "PONG :".substr($buffer, 6)."\r\n");
echo $buffer;
flush();
}
// break out of while, 0 bytes
/* $stream_meta_data = stream_get_meta_data($socket);
if($stream_meta_data['unread_bytes'] <= 0) {
break;
}*/
# join only one time
if($join_at_start === true && false === strpos($buffer, 'Your host is trying to (re)connect too fast -- throttled')) {
foreach($bot["Channels"] as $key => $channel) {
sendData("JOIN", $channel);
$join_at_start = false;
}
}
}
?>
</body>