Live Coding : Notifications temps réel avec Mercure

22 mai 2020 - : Javascript PHP Tutoriel Live-Coding - : 0 commentaire - Tutoriel Javascript PHP Live-Coding

Dernière modification le 23 mai 2020

Dans ce live-coding, nous traitons l'utilisation de Mercure, un serveur permettant de mettre en place des notifications en temps réel sur notre site.

Nous allons utiliser deux exemples :

  • Mettre en place des notifications générales de nouveau message dans un chat
  • Mettre en place des notifications individuelles de messages privés

ATTENTION : dans la vidéo j'utilise des notifications bootstrap. Le code ci-dessous n'entre pas dans tous les détails de la vidéo.

Pour ce faire, nous allons utiliser les fichiers exemple téléchargeables sur Github.

Installer et configurer Mercure

Installation

Avant de pouvoir l'utiliser, il est nécessaire d'installer Mercure.

Dans la vidéo et ci-dessous, j'utiliserai la version Windows. Pour les autres versions, merci d'utiliser les instructions disponibles sur le lien ci-dessus.

Nous commençons par télécharger l'archive qui nous intéresse pour nous la décompressons dans le dossier de notre choix.

Configuration

Mercure étant installé, il nous reste à le configurer et à le démarrer.

Pour la configuration, il nous faudra suivre différentes étapes.

Clé de sécurité

Nous devons définir une clé de sécurité, qui permettra de générer un jeton d'authentification pour nous permettre de sécuriser le serveur afin qu'il réponde uniquement aux requêtes légitimes.

Cette clé est une chaîne de caractères que vous seuls devez connaître. La clé de démonstration est !ChangeMe! et sera à modifier dans toutes les commandes ci-dessous.

Démarrer Mercure

Pour démarrer Mercure, j'utiliserai Powershell sur Windows et devrai définir plusieurs variables d'environnement qui serviront à la configuration.Vous trouverez sur chaque ligne la configuration proposée pour la démo.

  • JWT_KEY : clé de sécurité, je mettrai '!ChangeMe!'
  • ADDR : adresse de Mercure 'localhost:3000'
  • DEMO : environnement de démo '1'
  • ALLOW_ANONYMOUS : les requêtes anonymes sont-elles autorisées '1'
  • CORS_ALLOWED_ORIGINS : quelles origines sont autorisées pour les inscriptions '*'
  • PUBLISH_ALLOWED_ORIGINS : quelles origines sont autorisées pour les publications 'http://localhost:3000'

La commande pour exécuter Mercure sur Powershell sera donc la suivante

$env:JWT_KEY='!ChangeMe!'; $env:ADDR='localhost:3000'; $env:DEMO='1'; $env:ALLOW_ANONYMOUS='1'; $env:CORS_ALLOWED_ORIGINS='*'; $env:PUBLISH_ALLOWED_ORIGINS='http://localhost:3000'; .\mercure.exe

Une fois cette commande lancée, accédez à http://localhost:3000 et vous devriez arriver sur la page "Mercure Debugging Tools".

JSON Web Token

Pour la sécurité, Mercure utilise le JWT (JSON Web Token) qui doit être généré à partir de la clé de sécurité. Nous allons nous rendre sur le site jwt.io pour le générer.

Défilez la page jusqu'à atteindre la zone ci-dessous

JWT.io

Dans cette zone, à droite, dans "Payload: Data", entrez le json ci-dessous

{
  "mercure": {
    "subscribe": ["*"],
    "publish": ["*"]
  }
}

Ensuite, dans "Verify Signature", entrez votre clé de sécurité. Je vais entrer !ChangeMe!

Enfin, dans la partie "Encoded" à gauche, récupérez votre token que vous collerez dans la partie "JWT" de votre page "Mercure Debugging Tools".

Garder bien ce token en sécurité pour la suite, il sera nécessaire pour envoyer des notifications.

Votre serveur est maintenant prêt à fonctionner.

Notifications générales

Pour notifier tous les utilisateurs de la plateforme, lorsqu'un nouveau message a été publié dans le chat, par exemple, nous allons utiliser un "topic" de notification identique pour tous.

Ce topic, prenant la forme d'une url, sera par exemple "https://intro-mercure.test/users/chat". Il sera utilisé par notre navigateur pour "s'inscrire" auprès de Mercure pour recevoir les notifications.

Nous utiliserons donc le code javascript suivant pour nous inscrire

// Nous définissons l'URL de Mercure
const url = new URL('http://localhost:3000/.well-known/mercure');

// Nous ajoutons le topic pour les notifications générales de chat
url.searchParams.append('topic', 'https://intro-mercure.test/users/chat');

// Nous instancions l'évènement
const eventSource = new EventSource(url);

// La fonction de callback sera appelée chaque fois que un évènement sera publié
eventSource.onmessage = e => {
    // La variable e contient l'évènement et le message
    console.log(e)

    // Ici vous gérez la notification en récupérant ses données (e.data)
}

Pour envoyer une notification, nous allons tout d'abord créer une fonction PHP "universelle" qui permettra de simplifier l'envoi par la suite.

/**
 * Cette fonction envoie une notification au topic précisé avec les données fournies
 * @param string $topic topic sur lequel envoyer la notification
 * @param array $data données à envoyer
 * @return void 
 */
function mercurePost(string $topic, array $data = []){
    // On définit notre token
    define('DEMO_JWT', 'Entrez ici votre token JWT');

    // On crée le query string à envoyer
    $postData = http_build_query([
        'topic' => $topic,
        'data' => json_encode($data),
    ]);

    // On envoie le contenu à Mercure
    echo file_get_contents(
        'http://localhost:3000/.well-known/mercure',
        false,
        stream_context_create([
            'http' => [
                'method'  => 'POST',
                'header'  => "Content-type: application/x-www-form-urlencoded\r\nAuthorization: Bearer ".DEMO_JWT,
                'content' => $postData,
            ]
        ])
    );
}

A noter qu'il est également tout à fait possible de l'envoyer en utilisant Curl.

Avec cette fonction, envoyer un message de notification générale pourra par exemple prendre la forme suivante

// On définit le topic destinataire
$topic = 'https://intro-mercure.test/users/chat';

// On structure les données
$data = [
    'pseudo' => $_SESSION['user']['pseudo'],
    'message' => $message),
    'date' => date('Y-m-d H:i:s')
];

// On envoie
mercurePost($topic, $data);

Notifications individuelles

Pour notifier certains utilisateurs de la plateforme, lorsqu'un nouveau message personnel est reçu, par exemple, nous allons utiliser un "topic" de notification individuel.

Ce topic, prenant la forme d'une url, sera par exemple "https://intro-mercure.test/users/message/123" où 123 sera un identifiant unique, l'id utilisateur par exemple. Il sera utilisé par notre navigateur pour "s'inscrire" auprès de Mercure pour recevoir les notifications.

Nous utiliserons donc le code javascript suivant pour nous inscrire

// Nous définissons l'URL de Mercure (si elle n'a pas été définie précédemment
const url = new URL('http://localhost:3000/.well-known/mercure');

// Nous ajoutons le topic pour les notifications individuelles
url.searchParams.append('topic', 'https://intro-mercure.test/users/message/'+user);

// Nous instancions l'évènement
const eventSource = new EventSource(url);

// La fonction de callback sera appelée chaque fois que un évènement sera publié
eventSource.onmessage = e => {
    // La variable e contient l'évènement et le message
    console.log(e)

    // Ici vous gérez la notification en récupérant ses données (e.data)
}

Pour envoyer une notification, nous allons effectuer exactement les mêmes actions que dans le chapitre précédent.

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat

Les fichiers de cet article sont disponibles sur Github

Partager

Partager sur Facebook Partager sur Twitter Partager sur LinkedIn

Commentaires

Pas encore de commentaire

Obtenir de l'aide

Il n'est plus possible d'ajouter de commentaires.

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat