Notifications poussées depuis PHP, sans service intermédiaire

Les notifications poussées du web ont une réputation de complexité qu’elles ne méritent pas. Il n’y a pas de service tiers auquel s’inscrire, ni de protocole propriétaire.

Ce qu’est un abonnement

  • Un point de terminaison : une URL chez le service de poussée de l’éditeur du navigateur.
  • Une clé publique et un secret d’authentification, engendrés par le navigateur.

Votre serveur chiffre la charge utile avec ceux-là, et l’envoie en POST au point de terminaison. Le service de poussée la relaie sans jamais voir le contenu. C’est la partie que l’on rate : l’éditeur ne peut pas lire vos notifications, le chiffrement est de bout en bout entre votre serveur et le navigateur.

VAPID

Vous vous identifiez auprès du service de poussée avec un JWT signé, et c’est cela, VAPID. Une paire de clés pour toute votre application, et une adresse de contact pour que l’éditeur puisse vous joindre si quelque chose tourne mal. Rien à enregistrer.

Faites le ménage dans vos abonnements

Les abonnements expirent. Un utilisateur efface ses données, désinstalle, ou révoque la permission, et votre point de terminaison se met à renvoyer 404 ou 410. Ces deux codes veulent dire « supprimez cet abonnement », pas « réessayez plus tard ».

Une table de poussée que personne n’élague grossit indéfiniment et ralentit chaque envoi, parce que vous continuez de payer pour des requêtes qui ne peuvent jamais aboutir.

Le côté service worker

Le worker écoute push et appelle showNotification. Gardez ce gestionnaire trivial et synchrone dans l’esprit : un worker qui attend une récupération lente avant de rien afficher se fait tuer, et la notification n’apparaît jamais.

Cette panne est propre à la plateforme et discrète. pwa-bundle 1.5.8 a corrigé un cas où un événement de poussée était abandonné en silence sur Chrome pour Android, soit exactement le genre de bogue que vous ne pouvez pas reproduire sur votre poste.

web-push s’occupe du chiffrement et de la signature VAPID, avec un bundle Symfony.