无法在PHP IRC-BOT中发送预定的消息

时间:2016-04-19 07:46:47

标签: php sockets bots irc

我正准备在php中开发一个简单的irc bot。 上面的一半是从头开始的IRC bot的实现(连接套接字......等) 我要添加的功能是“计划通知” 当具体时间到来时,会发送一些消息。

例如, 当时间Tue Apr 19 16:32到来时,会发送一些通知消息。

因此,如果您设置(date("D") == "Tue" && date("H") == 15)之类的内容, 这应该是继续发送消息直到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");
    }

}

1 个答案:

答案 0 :(得分:1)

您的代码在读/写逻辑部分中被破坏 - 您当前的代码总是假设读取某些东西(将在某些事情发生之前一直睡觉),然后写一些东西。您需要添加缓冲区并使用poll / select。我认为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();
}