2016-04-19 10 views
0

Ich bin auf dem Weg, um eine einfache IRC Bot in PHP zu entwickeln. Die Hälfte oben ist eine Implementierung für IRC-Bot von Grund auf neu (Verbindung einer Steckdose .... Etc) Die Funktion, die ich hinzufügen möchte, ist "Zeitplan Benachrichtigung" Wenn die bestimmte Zeit kommt, werden einige Nachrichten gesendet.Nicht in der Lage, eine geplante Nachricht in PHP zu senden IRC-BOT

Zum Beispiel, wenn Zeit Tue Apr 19 16:32 kommt, wird eine Benachrichtigung Nachricht gesendet.

Also, wenn Sie so etwas wie (date("D") == "Tue" && date("H") == 15), setzen, soll dies weiter senden Nachricht bis 16:00 Uhr kommt.

Aber sobald der Bot in einen Kanal kommt, hört es auf, Nachrichten zu senden.

Ich nehme an, dass dies durch die Socket-Verbindung verursacht wird, aber ich weiß nicht wirklich die Ahnung.

<?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] 
    // :[email protected] PRIVMSG #bot-test :@arukas. 

    // Scheduler bot 
    if (date("D") == "Tue" && date("H") == 15) { 
     $saying = "REALLY SLEEPY!!"; 
     socket_write($socket, 'PRIVMSG ' . "CIRC1989" . " :$saying\r\n"); 
    } 

} 

Antwort

1

Ihr Code auf dem Lese-/Schreib-Logikteil unterbrochen wird - Ihr aktueller Code übernimmt immer etwas liest (wird tief, bis etwas passiert), dann etwas schreiben. Sie müssen Puffer hinzufügen und poll/select verwenden. Ich nehme an, dass php mindestens einer von ihnen ist.

Pseudocode, die funktionieren soll:

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(); 
} 
+0

Beachten Sie, dass timeout_until_next_event so hoch sein sollte, wie man wirklich weg will (so viele Sekunden wie der nächsten Timer-Tick für Ihr geplantes Ereignis, wirklich). Wenn Sie zu viel in der while-Schleife mit einem niedrigen Auswahl-Timeout laufen lassen, kann dies zu einer übermäßigen CPU-Auslastung führen. – braindigitalis