0

This is the basic connection code for a small PHP IRC bot. The problem is that it seems that the while() loop does not progress beyond fgets() until it receives data from the IRC server. I want the while() loop to iterate regardless if the IRC server has not yet sent data. Is this possible?

$socket = fsockopen($config['irc_server'], $config['port']);
while (1) 
{
    $data = fgets($socket, 128);
    echo '[RECEIVE] ' . $data;
    $recv = explode(' ', $data);

    if ($recv[0] == 'PING')
    {
        send('PONG', $recv[1]);
    }
}
Equinox
  • 13
  • 3

4 Answers4

2

Check out the socket_* functions including this one:

socket_set_nonblock

You can can also pass a non-block flag to socket_recv

Here is the obligatory quick and dirty example (no error checking)

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, $address, $service_port);
while (false === ($bytes = socket_recv($socket, $buf, 2048, MSG_DONTWAIT))) 
{ /* do stuff while waiting for data */ }
ChronoFish
  • 3,589
  • 5
  • 27
  • 38
0

Take a look at ftell. Here is a related example from the php documentation:

#!/usr/bin/php4 -q
<?
#following will hang if nothing is piped:
#$sometext = fgets(STDIN, 256)

$tell = ftell(STDIN);

if (is_integer($tell)==true) 
  {echo "Something was piped: ".fread(STDIN,256)."\n";}
else 
  {echo "Nothing was piped\n";}

?>
Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
0

stream_select() can tell if data is available for reading on the socket. But fgets() doesn't return until there's a line break or the stream ends. So you'd have to use fread() instead and split the data yourself.

btw: You might also be interested in the PEAR::Net_SmartIRC package.

VolkerK
  • 95,432
  • 20
  • 163
  • 226
-1

The problem is that it seems that the while() loop does not progress beyond fgets() until it receives data from the IRC server.

I don't see how that's a problem. What do you want that code to do if it receives nothing?

At the moment, it'll just loop around back to the fgets again, so you're just burning cycles busy-waiting for no good reason. Blocking is the correct behaviour in this instance.

Anon.
  • 58,739
  • 8
  • 81
  • 86
  • He could, conceivably, want the bot to say something periodically, even when it receives no input. Think of, for example, those trivia bots. Even if the room's silent, they ask a new question every 60 seconds, or whatever. Similarly, DCC bots often advertise themselves every few minutes. – Frank Farmer Dec 11 '09 at 01:03