socket_stream_select: Attendre un flux (stream) et un socket en même temps

Avec PHP, on peut interagir avec l’extérieur (et l’intérieur) du serveur sur lequel est exécuté le PHP à l’aide de flux et de sockets. Pour PHP, les flux – ou streams – et les sockets sont différents, alors qu’au niveau système, ce sont en réalité tous les deux des sockets (différents des sockets tels que l’entend PHP).

L’on travaille sur les deux en utilisant des fonctions toutes distinctes:

Parmi celles-ci, il y a deux fonctions extrêmement utiles: stream_select et socket_select. Elles permettent d’attendre de nouvelles données respectivement depuis un flux et un socket.

Vous pouvez par exemple attendre deux flux de données en même temps avec stream_select. Si l’un des deux a de nouvelles informations, la fonction retourne un entier décrivant le nombre de flux qui ont eu de nouvelles notifications. Vous pouvez aussi ajouter un timeout, etc… De la même manière, vous pouvez attendre un ou plusieurs sockets avec socket_select.

Seulement, si vous travaillez à la fois avec des flux et des sockets… Comment faire?

  1. Vous pouvez très bien mettre des timeout à quelques dizaines de millisecondes, regarder pendant x ms le flux, x ms le socket, puis on recommence… C’est une solution comme une autre mais très peu propre, et qui ne sera jamais “instantanée”.
  2. Vous pouvez utiliser un système, auquel vous vous connecterez en socket, qui écoutera un flux et dès que le flux recevra des données, il vous l’enverra par le socket. Ainsi, vous aurez que des sockets, vous pouvez donc utiliser socket_select.
  3. Mais, pourquoi ne pas créer une fonction socket_stream_select, ou stream_socket_select, comme vous voulez, dans le coeur de PHP, qui transformera les flux et les sockets PHP en sockets systèmes pour les écouter avec la fonction C select ?

Une fonction socket_stream_select

Elle aurait très bien pu s’appeller stream_socket_select mais les fonctions socket_* étant présentes uniquement lorsque PHP est compilé avec --enable-socket, et que les flux sont toujours présents, a fait que mon choix s’est porté vers l’ajout d’une fonction à l’extension “socket” de PHP.

La fonction socket_stream_select ressemble à socket_select et stream_select, mais elle prend 8 paramètres, qui sont décrit après son prototype que voilà:

int socket_stream_select ( array &$read_streams, array &$read_sockets, array &$write_streams, array &$write_sockets, array &$except_streams, array &$except_sockets, int $tv_sec [, int $tv_usec])

  • $read_streams
    Flux surveillés pour la lecture
  • $read_sockets
    Sockets surveillés pour la lecture
  • $write_streams
    Flux surveillés pour l’écriture
  • $write_sockets
    Sockets surveillés pour l’écriture
  • $except_streams
    Flux surveillés pour leurs exceptions
  • $except_sockets
    Sockets surveillés pour leurs exceptions
  • Les paramètres $tv_sec (en secondes) et $tv_usec (en millisecondes) forment le paramètre timeout (durée de vie). Le timeout est la durée maximale de temps avant que socket_stream_select() ne se termine. $tv_sec peut être zéro, ce qui fera que socket_stream_select() retournera immédiatement. C’est très pratique pour faire du polling (sondage). Si $tv_sec est NULL (pas de timeout), socket_stream_select() peut se bloquer indéfiniment.

Installation de la fonction socket_stream_select

Pour pouvoir bénéficier de la fonction socket_stream_select, vous devez utiliser votre propre version de PHP, que vous aurez préalablement patchée avec le patch pour socket_stream_select, puis compiler avec l’option –enable-socket.

Le patch se trouve à cette adresse:

Dans le dossier des sources de PHP 5.3, il vous suffit d’exécuter ces deux commandes afin de créer cette fonction socket_stream_select dans le coeur de PHP:

Bonne continuation. :-)

facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">