From 9a97c71087e7fdaf00df523d0dfde7f7d3bb2482 Mon Sep 17 00:00:00 2001 From: denmigda Date: Tue, 12 Dec 2023 08:33:15 +0100 Subject: [PATCH] add ServerSendEvent --- Readme.md | 10 ++- .../index.md | 87 ++++++++++++++++++- 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index ed16822..c4cf75a 100644 --- a/Readme.md +++ b/Readme.md @@ -21,11 +21,15 @@ include_toc: true 1. [Communications Client-Serveur](./Web/X%20-%20Communications%20Client-Serveur/index.md) - - [ ] REST + - [ ] Le serveur Web + + - [ ] REST + routes {name} cf Moodle + + - [ ]  OPTI REST API (cf youtube) - [ ] WebSocket - - [ ] ServerEvent + - [ ] Move optimisation 2 [F] 5. [F] Perfs et SEO - [partie opti de com' Client-Serveur] @@ -37,7 +41,7 @@ include_toc: true 3. [D-TS] TS avancé -4. [X] WebComponents en vrai / Animations / transitions / canvas +4. [X] WebComponents en vrai / Animations / transitions / canvas / WebWorker 5. [X] WebPack / CI/CD / unit tests / tests de recettes (en pratique) / validation des données runtime diff --git a/Web/X - Communications Client-Serveur/index.md b/Web/X - Communications Client-Serveur/index.md index 80c119e..0c422ff 100644 --- a/Web/X - Communications Client-Serveur/index.md +++ b/Web/X - Communications Client-Serveur/index.md @@ -138,4 +138,89 @@ BDD API/FileAPI ## Websocket -## Server event +🚩 [TODO] + +## Server Send Event + + + +Contrairement aux WebSockets, les *Server Send Events* ne permettent qu'une communication unidirectionnelle du serveur vers le client. Il est utilisé lorsque le serveur doit régulièrement envoyer des informations au client, sans attendre de réponses, e.g. envoyer des logs en temps réel. + +Le principe est très simple, il s'agit d'une requête et d'une réponse HTTP normales, à l'exception que la réponse HTTP est maintenue en vie (`keep-alive`) et est écrite petit à petit (`text/event-stream`). Le corps de la réponse suit le format suivant : + + +``` +event: $EVENT_NAME +data: $DATA + +event: $EVENT_NAME +data: $DATA + +event: $EVENT_NAME +data: $DATA +``` + +Côté client, l'utilisation est très simple, il suffit d'écouter des événements d'un `EventSource`. + + + +```javascript +// [JS] JavaScript + +// Client +const servEvent = new EventSource($URL); +servEvent.addEventListener($EVENT_NAME, function(ev) { + console.log(ev.data) +}); +servEvent.close(); // termine la communication. + + +// Serveur (helper) +class SSE { + constructor(res) { + this.res = res; + this.#setHeaders + } + #setHeaders() { + this.res.set({ + 'Cache-Control': 'no-cache', + 'Content-Type' : 'text/event-stream', + 'Connection' : 'keep-alive' + }); + this.res.flushHeaders(); + } + dispatchEvent(name, data) { + this.res.write(`event: ${name}\n${data}\n\n`); + } +} + +// Serveur +app.get($URL, async function(req, res) { + + const sse = new SSE(res); + + sse.dispatchEvent($EVENT_NAME, $DATA); // Envoyer un event. +}); +``` + +```python +# [🐍] Python + +# Client +def handler(ev): + console.log(ev.data) + +const servEvent = EventSource.new($URL); +servEvent.addEventListener($EVENT_NAME, handler); +servEvent.close(); # termine la communication. + +# Serveur +# pip3 install aiohttp_sse +from aiohttp_sse import sse_response + + +async def GET(request): + req = sse_response(request) + + req.send($DATA, event=$EVENT_NAME) # Envoyer un event. +```