2009-12-11 3 views
0

Ceci est le code de connexion de base pour un petit robot PHP IRC. Le problème est qu'il semble que la boucle while() ne progresse pas au-delà de fgets() jusqu'à ce qu'elle reçoive des données du serveur IRC. Je veux que la boucle while() se répète, même si le serveur IRC n'a pas encore envoyé de données. Est-ce possible?Comment une boucle while() peut-elle rester bloquée lors de l'utilisation de fsockopen() et de fgets() en PHP?

$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]); 
    } 
} 
+1

Pensez "non-bloquant" –

Répondre

-1

Le problème est qu'il semble que la boucle while() ne progresse pas au-delà fgets() jusqu'à ce qu'il reçoive les données du serveur IRC.

Je ne vois pas comment cela est un problème. Que voulez-vous que ce code fasse s'il ne reçoit rien?

Pour l'instant, il suffit de revenir en boucle sur les fgets, de sorte que vous ne faites que brûler des cycles chargés-en attendant sans raison valable. Le blocage est le comportement correct dans cette instance.

+0

Il pourrait, peut-être, vouloir que le bot dise quelque chose périodiquement y, même quand il ne reçoit aucune entrée. Pensez, par exemple, à ces trivia bots. Même si la pièce est silencieuse, ils posent une nouvelle question toutes les 60 secondes, ou peu importe. De même, les robots DCC se font souvent de la publicité toutes les quelques minutes. –

0

Jetez un coup d'œil à ftell. Voici un exemple de la documentation connexe php:

#!/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";} 

?> 
0

stream_select() peut dire si les données sont disponibles pour la lecture sur la prise. Mais fgets() ne retourne pas tant qu'il n'y a pas de saut de ligne ou que le flux se termine. Donc, vous devrez utiliser fread() à la place et diviser les données vous-même.

btw: Vous pourriez également être intéressé par le paquet PEAR::Net_SmartIRC.

2

Vérifiez les fonctions socket_ * dont celui-ci:

socket_set_nonblock

Vous pouvez pouvez également passer un drapeau non-bloc à socket_recv

Voici l'obligatoire exemple rapide et sale (pas d'erreur vérification)

/* 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 */ } 
Questions connexes