Appuyez sur Entrée pour rechercher

Serveur chat en 20 minutes (ReactPHP)

Author Avatar
Mario Aquino
Business Consultant

ReactPHP est un ensemble de progiciels, qui permet d'écrire du PHP asynchrone. Les opérations de machine sont plus de 100 fois plus rapides que les opérations I/O. ReactPHP gagne en performance en n'attendant pas la fin des opérations I/O et exécutera « le prochain code » à la place. ReactPHP fonctionne plus rapidement car il utilisera votre fil de la manière la plus efficace.

À ne pas confondre avec la programmation parallèle, quand un nouveau fil de discussion est ouvert lorsque votre fil d'origine est bloqué par une opération I/O. La programmation parallèle pose des problèmes tels que l'isolation, la sécurité des fils de discussion et la lenteur du changement de contexte. Plus important encore, le programme devient inutilement complexe.

Les applications Web PHP fonctionnent déjà en parallèle, un nouveau fil est ouvert pour chaque connexion. De cette façon, l'utilisateur A n'est jamais bloqué par les opérations de l'utilisateur B. ReactPHP peut être une amélioration de ce modèle, nous gardons toujours un fil pour chaque utilisateur, mais ReactPHP utilisera ce fil à sa capacité maximale.

Cet article couvre quelques concepts de base pour comprendre le fonctionnement des progiciels ReactPHP. Assurez-vous de le lire jusqu'à la fin, car dans le dernier paragraphe, nous allons configurer un serveur Websocket performant, conçu pour fonctionner indéfiniment.

Concepts de base

Boucle d'événement

« Dans ReactPHP, tout fonctionne de manière asynchrone, à l'exception de votre code. »

Cela peut sembler étrange, car le paragraphe précédent mentionnait que ReactPHP fonctionne de manière asynchrone. Commençons par expliquer l'interprétation de ce script simple :

Image 1

 

Phases du programme :

  1. Début du programme
  2. Enregisterment de la boucle d'événement et des événements
  3. Exécution de la boucle d'événements définie
  4. Exécution de la boucle d'événements définie
  5. Exécution de la boucle d'événements définie

Dans la phase 2, les événements sont enregistrés (dans cet exemple, les événements temporels), dans les phases suivantes, nous vérifierons quels événements sont enregistrés et si l'un d'entre eux est déclenché. Les phases mentionnées s'exécutent toutes de manière synchrone, mais il y a plus que cela. Nous devons faire un gros plan de la « Boucle d'événements » pour comprendre pourquoi ReactPHP fonctionne de manière asynchrone :

Phases de la Boucle d'événements :

Image 2

La boucle dans le code ci-dessus pourrait être exécutée plus de 100x, mais elle imprimera seulement des données après 1 et après 2 secondes. Veuillez noter que l'ordre des événements n'est pas important ; l'événement après 1 seconde sera d'abord exécutée, bien que l'événement après 2 secondes soit défini d'abord. C'est pourquoi ReactPHP fonctionne de manière asynchrone.

Image 3

Ce concept est le même pour les opérations I/O, peu importe le moment de démarrage de l'opération, ReactPHP n'interagira avec elle que lorsqu'elle aura quelque chose (données) à fournir.

Flux

Le contrôle des événements de temporisation dépassés n'est qu'une phase de la boucle d'événements, la deuxième phase comprend l'interrogation des opérations I/O. Il s'agit d'un contrôle permettant de vérifier si l'une des opérations I/O enregistrées précédemment a déjà des résultats. Une opération I/O peut comprendre plusieurs choses : des opérations sur un fichier, des opérations de base de données, des appels d'API, des commandes d'imprimante, … Et bien d'autres !

Presque toutes les opérations I/O correspondent au niveau le plus bas des flux, un élément important de la bibliothèque ReactPHP.

Image 4

Dans cet exemple nous distinguons 3 flux importants :

  1. ReadableResourceStream – STDIN
    1. Dans cet exemple, le flux d'entrée correspond à ce que l'utilisateur écrit dans le terminal (=STDIN)
  2. ThroughStream
    1. Ce flux agit comme un « intergiciel » entre le flux d'entrée et de sortie, nous pourrions effectuer des activités telles que transformer le texte en majuscules, retirer les grossièretés, … Ou dans le contexte de chat, ajouter le nom de l'expéditeur au message. Pour l'exemple, nous mettrons le texte en majuscules.
  3. WriteableResourceStream – STDOUT
    1. C'est la destination de notre message, dans cet exemple, le résultat sera mis dans le terminal (= STDOUT)

 

Image 5

Veuillez noter que ce script s'exécutera indéfiniment puisque le flux d'entrées attendra que l'utilisateur tape quelque chose… Si le flux d'entrée devait lire un fichier, le script se terminerait au moment d'atteindre la fin du fichier.

Plus d'informations sur les concepts de base

Avec ces deux concepts de base, vous devriez avoir une bonne compréhension du fonctionnement des progiciels ReactPHP. Il y a des concepts plus basiques, si vous êtes intéressé, assurez-vous de regarder ma vidéo de conférence :

 

 

CServeur de discussion utilisant les websockets de ReactPHP

Websockets

Pour mieux comprendre les websockets, nous devons d'abord jeter un œil à une connexion HTTPS régulière. Lorsqu'un client accède à blog.easi.net, voici à quoi ressemble la prise de contact HTTPS :

Image 6

  1. Le client demande une connexion au serveur
  2. Le serveur acceptera cette demande
  3. Le client ouvre la connexion (la connexion est établie)
  4. Étapes de configuration SSL
  5. Le client demandera le site blog.easi.net
  6. Le serveur fournit tout le nécessaire pour blog.easi.net
  7. Le client notifiera le serveur lorsque tout sera téléchargé (demande de fermeture de la connexion)
  8. Le serveur ferme la connexion

Comme vous pouvez le constater, il y a une certaine surcharge avant que la connexion ne soit établie et fermée. Cette surcharge n'est pas une erreur lorsque vous demandez tout un site Web au serveur. Autre détail important, le serveur ne pourra pas initier de connexion avec le client. Le client doit commencer par une requête (blog.easi.net).

Le cas d'utilisation le plus populaire pour les websockets est un chat d'utilisateur à utilisateur. Imaginons que deux utilisateurs souhaitent discuter par chat (disons Bob et Alice). Notre modèle HTTPS causerait deux gros problèmes :

  1. Bob et Alice ne recevront des messages que lorsqu'ils actualiseront activement la page ou lorsque leur navigateur enverra une requête au serveur. (Vous pouvez résoudre ce problème avec l'interrogation, mais cela épuisera la bande passante.)

  2. Performance/overhead, la poignée de main en 7 étapes doit être effectuée deux fois pour chaque message envoyé entre les utilisateurs. La connexion ne devrait jamais être fermée car nous savons qu'il y aura d'autres messages.

Il s'agit d'un cas d'utilisation où les Websockets sont utiles ; une connexion websocket restera ouverte entre le client et le serveur. Le schéma de connexion restera le même, seules les étapes 7 et 8 ne seront pas exécutées. Comme la connexion reste ouverte, la poignée de main ne devrait avoir lieu que deux fois (une fois pour Bob, une fois pour Alice).

En utilisant des Websockets, nous gagnons du temps, de la bande passante et le plus important : cela renforce l'expérience utilisateur. Bob recevra les messages d'Alice instantanément et vice versa.

Dans ReactPHP, nous pourrions configurer un tel serveur de discussion (websocket) en 22 lignes de code :

Image 7

Il y a 3 objets importants à comprendre dans cet exemple de code :

  • $server est un serveur Websocket de base, qui dans ce cas est configuré pour écouter sur le port 6000. Ce socket-serveur ouvre les connexions mais n'en garde pas la trace. C'est suffisant pour la communication client - serveur, mais pas assez pour notre cas d'utilisation de chat. Nous avons besoin d'une connexion client – serveur – client
  • $limitingServer est une version améliorée de notre $server mentionné, le deuxième paramètre est utilisé pour configurer le nombre de connexions au serveur autorisées. (Dans cet exemple 10) Une autre chose importante à savoir est que le serveur de limitation garde une trace des notes connectées. À tout moment, le serveur de limitation pourra nous dire combien de connexions ouvertes il reste.
  • $client est dans cet exemple la connexion d'un utilisateur à notre serveur socket.

À l'exception des trois objets mentionnés, il n'y a rien de nouveau dans ce script. Il y a deux événements enregistrés qui définissent comment notre serveur doit réagir :

  • Lorsqu'un utilisateur se connecte (« connexion ») : Envoi du message « Bienvenue ! » à l'utilisateur
  • Lorsqu'un utilisateur envoie un message (« data ») : Distribution du message à toutes les connexions ouvertes et envoi d'une confirmation d'envoi à l'expéditeur.

Conclusion

ReactPHP est un outil puissant, qui peut augmenter les performances et la réactivité de votre application. ReactPHP peut être utilisé en tant que projet autonome ou alors, les progiciels peuvent être installés/ajoutés dans votre projet/framework existant.

Il est recommandé d'utiliser ReactPHP pour les tâches de longue durée ou les tâches qui nécessitent de nombreuses opérations I/O. Cela peut être une excellente alternative pour Node.js/Go, surtout si vous connaissez déjà PHP et que les autres technologies seraient nouvelles pour vous.

Références

New call-to-action

Offres d'emploi actuelles

Nous sommes toujours à la recherche de nouveau collègues

Si vous partagez nos valeurs et que vous êtes à la recherche d'un emploi stimulant au sein du meilleur lieu de travail de Belgique, visitez notre site web.

Postule maintenant

Abonnez-vous

Suivez-nous

  

Partage cet article