我正在用php开发一个简单的irc bot。上面的一半是IRC机器人程序的从头开始的实现(连接套接字等)我想添加的功能是"日程通知"当特定时间到来时,会发送一些消息。
例如,当时间Tue Apr 19 16:32
到来时,发送一些通知消息。
因此,如果设置类似CCD_ 2的内容,这应该一直发送消息,直到16:00到来。
但是一旦机器人进入通道,它就会停止发送消息
我想这是由套接字连接引起的,但我真的不知道其中的线索。
<?php
// Time zone setting
date_default_timezone_set('Asia/Tokyo');
// Our bot's configuration parameters.
$server = '192.168.59.103';
$port = 6667;
$nickname = 'Bot';
$ident = 'Bot';
$gecos = 'Bot v1.0';
$channel = '#bot-test';
// Connect to the network
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$error = socket_connect($socket, $server, $port);
// Add some error handling in case connection was not successful.
if ($socket === false){
$errorCode = socket_last_error();
$errorString = socket_strerror($errorCode);
die("Error $errorCode: $errorString 'n");
}
// Send the registration info.
socket_write($socket, "NICK $nickname'r'n");
socket_write($socket, "USER $ident * 8 :$gecos'r'n");
// Finally, loop until the socket closes.
while (is_resource($socket)) {
// Fetch the data from the socket
$data = trim(socket_read($socket, 1024, PHP_NORMAL_READ));
echo $data . "'n";
// Splitting the data into chunks
$d = explode(' ', $data);
// Padding the array avoids ugly undefined offset erros.
$d = array_pad ($d, 10, '');
// Our ping handler.
// Ping: $servername.
if ($d[0] === 'PING') {
socket_write($socket, 'PONG ' . $d[1] . "'r'n");
}
if ($d[1] === '376' || $d[1] === '422') {
socket_write($socket, 'JOIN ' . $channel . "'r'n");
}
// Bot collections
// "$d" parameter format
// [0] [1] [2] [3]
// :Nickname!ident@hostname PRIVMSG #bot-test :@arukas.
// Scheduler bot
if (date("D") == "Tue" && date("H") == 15) {
$saying = "REALLY SLEEPY!!";
socket_write($socket, 'PRIVMSG ' . "CIRC1989" . " :$saying'r'n");
}
}
您的代码在读/写逻辑部分被破坏了-您当前的代码总是假设读取一些东西(将休眠直到发生一些事情),然后写入一些东西。您需要添加缓冲区并使用轮询/选择。我假设php至少是其中之一。
应该工作的伪代码:
readbuffer[]
writebuffer[]
while (no_error)
{
if (writebuffer not empty)
{
select(socket, want_to_write, want_to_read, timeout_until_next_event);
} else {
select(socket, 0, want_to_read, timeout_until_next_event);
}
if (select return can write)
{
retval = write(socket, writebuffer);
if (no_error)
writebuffer.removefromstart(retval);
}
if (select return can read)
{
retval = read(socket, readbuffer + offset already filled);
if (no_error)
{
parse as much as possible in readbuffer, removing data as parsed;
}
}
check_timers();
}