现在我有机器人在机器人加入时发送消息。但是,如何制作一个可以发布数据的表单,以便机器人将消息发送到频道?
这是我的剧本(Rewamped):
<?php
set_time_limit(0);
$socket = fsockopen("//", 6667) or die();
$msg = $_POST['message'];
$pr = $_POST['percentage'];
$pr /= 100;
fputs($socket,"USER BOT 0 zo :ZH bot\n");
// Set the bots nickname
fputs($socket,"NICK BOT1\n");
fputs($socket,"JOIN #bots\n");
while(1) {
while($data = fgets($socket, 128)) {
// echo the data received to page
echo nl2br($data);
// flush old data, it isn't needed any longer.
flush();
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$search_string = "/^:([A-Za-z0-9_\-]+)[@!~a-zA-Z0-9@\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/";
$do = preg_match($search_string, $data, $matches);
// check that there is a command received
if(isset($matches['2'])) {
switch($matches['2']) {
case "PRIVMSG":
$user = $matches['1'];
$channel = $matches['3'];
$chat_text = isset($matches['4']) ? $matches['4'] : "";
// check chat for !time
if(strtolower($chat_text) == "!time") {
$output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::";
fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n");
} elseif(strtolower($chat_text) == "!hello") {
fputs($socket, "PRIVMSG " . $channel . " :Hello!\n");
}
break;
case "JOIN":
$user = $matches['1'];
$channel = $matches['3'];
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n");
break;
}
}
}
}
?>
E.g。制作一个将数据发送到IRC频道的表单。输出将是“wget file info port”&lt; - 这将是发送到IRC频道的文本。
以下是相关部分:
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel ."\n");
希望有人可以提供帮助。
答案 0 :(得分:3)
好的,这是一个更好的答案。第一部分仍然有效。每次要启动新脚本时都会调用一个新的PHP进程。因此,您需要一些方法来进行IPC。
以下是在PHP中使用* nix(但不是windows)的方法:
<强>接收器:强>
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
}
// Join the queue
$queue = msg_get_queue($queueKey);
while(!($queue == false)) {
// Note: This function could block if you feel like threading
$msgRec = msg_receive(
$queue, // I: Queue to get messages from
0, // I: Message type (0 = first on queue)
$msgType, // O: Type of message received
1024, // I: Max message size
$msgData, // O: Data in the message
true, // I: Unserialize data
MSG_IPC_NOWAIT // I: Don't block
);
if($msgRec) {
echo "Message received:\n";
echo "Type = $msgType\n";
echo "Data = \n";
print_r($msgData);
}
}
?>
<强>发件人:强>
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
} else {
echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}
$queue = msg_get_queue($queueKey);
$abc["something"] = "something value";
$abc["hello"] = "world";
$abc["fu"] = "bar";
msg_send(
$queue, // Queue to send on
1, // Message type
$abc, // Data to send
true, // Serialize data?
true // Block
);
?>
这应该产生(在接收器循环中)类似于此的东西:
Message received:
Type = 1
Data =
Array
(
[something] => something value
[hello] => world
[fu] => bar
)
您的脚本可能看起来像这样
postToMe.php:
<?php
$queueKey = 123321;
$queue = false;
if(msg_queue_exists($queueKey)) {
echo "Queue Exists.\n";
} else {
echo "WARNING: Queue does not exist. Maybe no listeners?\n";
}
$queue = msg_get_queue($queueKey);
msg_send(
$queue, // Queue to send on
1, // Message type
$_POST, // Data to send
true, // Serialize data?
true // Block
);
?>
bot.php:
<?php
set_time_limit(0);
$socket = fsockopen("//", 6667) or die();
$msg = $_POST['message'];
$pr = $_POST['percentage'];
$pr /= 100;
fputs($socket,"USER BOT 0 zo :ZH bot\n");
// Set the bots nickname
fputs($socket,"NICK BOT1\n");
fputs($socket,"JOIN #bots\n");
$queueKey = 123321;
$queue = false;
// Join the IPC queue
$queue = msg_get_queue($queueKey);
if(!$queue) echo "ERROR: Could not join IPC queue. Form data will not be received";
while(1) {
// Handle new post info
// You may want to increase the message size from 1024 if post data is large
if(msg_receive($queue, 0, $msgType, 1024, $msgData, true, MSG_IPC_NOWAIT)) {
// Handle data here. Post data is stored in $msgData
}
while($data = fgets($socket, 128)) {
// echo the data received to page
echo nl2br($data);
// flush old data, it isn't needed any longer.
flush();
$ex = explode(' ', $data);
if($ex[0] == "PING") fputs($socket, "PONG ".$ex[1]."\n");
$search_string = "/^:([A-Za-z0-9_\-]+)[@!~a-zA-Z0-9@\.\-]+\s*([A-Z]+)\s*[:]*([\#a-zA-Z0-9\-]+)*\s*[:]*([!\#\-\.A-Za-z0-9 ]+)*/";
$do = preg_match($search_string, $data, $matches);
// check that there is a command received
if(isset($matches['2'])) {
switch($matches['2']) {
case "PRIVMSG":
$user = $matches['1'];
$channel = $matches['3'];
$chat_text = isset($matches['4']) ? $matches['4'] : "";
// check chat for !time
if(strtolower($chat_text) == "!time") {
$output = "::::: " . date('l jS \of F Y h:i:s A') . " :::::";
fputs($socket, "PRIVMSG " . $channel . " :" . $output . "\n");
} elseif(strtolower($chat_text) == "!hello") {
fputs($socket, "PRIVMSG " . $channel . " :Hello!\n");
}
break;
case "JOIN":
$user = $matches['1'];
$channel = $matches['3'];
fputs($socket, "PRIVMSG " . $channel . " :Welcome " . $user . " to " . $channel . "\n");
break;
}
}
}
}
?>
答案 1 :(得分:2)
基本上,此脚本将一直运行。 PHP的工作方式是,对于每个正在运行的脚本,都会创建一个新的PHP进程。脚本可以同时运行多次,但是它们无法直接通信。
您需要创建另一个脚本(或者至少是这个脚本的全部新功能)来接受post变量,然后将它们发送到此脚本的运行版本。
(注意:我将提供2个解决方案,因为1非常困难。另外,我刚刚发现了Semaphore,但我不确定这是否符合我们的需求,因为我对它几乎一无所知{{ 3}})
最佳(但高级)
我能想到的最佳方式是使用套接字(特别是在* nix上,因为套接字对于IPC [进程间通信]来说非常棒)。这有点困难,因为你基本上只是为了传达细节而创建一个客户端/服务器,那么你需要为你的IPC提出某种协议。
我不会在这里编写任何代码,但与此相关的链接是 http://php.net/manual/en/book.sem.php http://www.php.net/manual/en/function.socket-bind.php http://www.php.net/manual/en/function.socket-create.php http://www.php.net/manual/en/function.socket-accept.php http://www.php.net/manual/en/function.socket-listen.php
如果在* nix上使用此功能,我强烈建议您使用AF_UNIX作为域名。它非常有效,而且很多应用程序都将它用于IPC。
优点: 非常强大的解决方 - 高效 - 即时(或尽可能接近)沟通
缺点: - 很难实施
不太好(但仍然很好)
只需使用文件来传达信息。让您的机器人脚本每15秒检查一次文件是否有变化。我建议使用XML作为数据(因为简单的xml使php中的xml处理很简单......)
您需要考虑的事情是: 如果同时收到2个帖子会有什么反应? (如果您只是使用平面文件或不考虑有多个条目,这将成为一个问题)。 如何判断消息是否是新消息(我在阅读后立即删除/删除文件。注意:处理后没有,因为有人可以在处理/发送消息时发布到表单脚本)
链接: 如何使用简单的xml http://www.php.net/manual/en/function.socket-connect.php http://au2.php.net/manual/en/book.simplexml.php
文件相关 http://php.net/manual/en/simplexml.examples-basic.php http://au2.php.net/manual/en/function.file-get-contents.php
话虽如此,您还可以使用MySQL / Postgres或其他一些数据库后端来处理脚本之间的数据流。
优点: - 易于实施
缺点: - 缓慢传输数据(按给定间隔检查文件) - 使用外部文件,可以删除/修改我的外部应用程序/用户