Chat : Interface


1Contrôleur

Nous verrons ici uniquement le contrôleur qui permet de charger l'interface web.

Les contrôleurs Message et Event, qui servent à communiquer avec le serveur pour envoyer et recevoir des messages, sont détaillés dans la page suivante du tutoriel.

Voici le code du contrôleur Homepage, enregistré dans le fichier controllers/Homepage.php :

<?php

/** Contrôleur racine. */
class Homepage extends \Temma\Web\Controller {
    /** Action racine. */
    public function __invoke() {
        $this->_view('homepage.tpl');
    }
}
  • Ligne 4 : Définition du contrôleur Homepage.
  • Ligne 6 : Définition de la méthode __invoke(), correspondant à l'action racine du contrôleur.
  • Ligne 7 : La méthode ne contient que l'instruction qui définit que le template à utiliser est le fichier homepage.tpl.

2Template

Voici le code du template templates/homepage.tpl qui est chargé au moment où l'utilisateur accès au service :

<!DOCTYPE html>
<html>
<body>
    {* formulaire d'envoi de message *}
    <input id="from" type="text" placeholder="Nom" autofocus>
    <input id="text" type="text" placeholder="Message">
    <button onclick="sendMessage()">Envoyer</button>

    {* liste qui va contenir les messages reçus *}
    <ul id="liste"></ul>

    {* chargement du code javascript *}
    <script src="/chat.js"></script>
</body>
</html>
  • Lignes 5 à 7 : Formulaire servant à envoyer des messages. Le premier champ attend le nom de l'utilisateur, le second attend le texte du message. En cliquant sur le bouton "Envoyer", la fonction Javascript sendMessage() est exécutée, et elle envoie les données du formulaire vers le serveur avec une requête AJAX.
  • Ligne 10 : Cette liste contiendra un élément supplémentaire à chaque fois qu'un message sera reçu.
  • Ligne 13 : Le fichier qui contient le code Javascript est chargé.

3Code Javascript

Voici le code Javascript enregistré dans le fichier www/chat.js :

/* *** RÉCEPTION DES MESSAGES PAR SSE *** */
// connexion à la source SSE
const evtSource = new EventSource("/event/fetch");
// écoute des événements envoyés sur le canal "msg"
evtSource.addEventListener("msg", function(event) {
    // création de l'élément DOM <li>
    const newElement = document.createElement("li");
    // désérialisation de l'événement reçu
    var evtData = JSON.parse(event.data);
    // ajout du message dans la liste
    newElement.textContent = evtData.from + " : " + evtData.text;
    // ajout de l'élément à la liste dans la page
    document.getElementById("liste").appendChild(newElement);
});

/* *** ENVOI DE MESSAGES AU SERVEUR *** */
// fonction appelée pour envoyer les messages au serveur
function sendMessage() {
    // récupération des valeurs du formulaire
    const from = document.getElementById("from").value;
    const text = document.getElementById("text").value;
    // création de l'objet de paramètres POST
    const formData = new FormData();
    formData.append("from", from);
    formData.append("text", text);
    // envoi des données en AJAX
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/message/broadcast", true);
    xhr.send(formData);
}

La première partie du code s'occupe d'ouvrir la communication SSE qui permettra de recevoir des événements provenant du serveur. La seconde partie est la fonction qui est appelée lors d'un envoi de message.

  • Ligne 3 : Connexion à la source des événements SSE, disponible à l'URL /event/fetch.
  • Lignes 5 à 14 : Code exécuté à chaque fois qu'un événement SSE est reçu sur le canal "msg".
    • Ligne 7 : Création d'un nœud <li>, correspondant à l'élément qui va contenir le message, et qui sera ajouté à la liste dans la page web.
    • Ligne 9 : Désérialisation des données (qui sont reçues au format JSON).
    • Ligne 11 : Dans l'élément <li> créé plus haut, on écrit un texte constitué du nom de l'expéditeur du message, suivi de " : " puis du message textuel reçu.
    • Ligne 13 : L'élément <li> est ajouté à la liste présente dans la page web.
  • Lignes 18 à 30 : Fonction appelée quand l'utilisateur clique sur le bouton "Envoyer" du formulaire.
    • Lignes 20 et 21 : Récupération des données du formulaire.
    • Lignes 23 à 25 : Création d'un objet FormData contenant les données du formulaire.
    • Lignes 27 à 29 : Envoi des données en AJAX sur l'URL /message/broadcast.