FreeToGenerate.com

Un événement sans champ data n’est jamais distribué : aucun écouteur, aucune erreur, rien. Rien n’est envoyé.

Essayez :

Le corps d’une réponse text/event-stream. Les lignes peuvent se terminer par un saut de ligne, un retour chariot, ou les deux.

Événements qui partent

TypeDonnéesDernier identifiant
progress{"percent": 40}1
messagestill working1

Ce qu’a fait chaque ligne

LigneContenuEffet
1:okUn commentaire, ignoré. C’est ainsi qu’on écrit habituellement un signal de maintien.
2retry: 3000A fixé le délai de reconnexion
3ligne videN’a rien distribué : le tampon de données était vide
4id: 1A fixé le tampon du dernier identifiant
5event: progressA fixé le type du prochain événement
6data: {"percent": 40}Ajouté au tampon de données, plus un saut de ligne
7ligne videA distribué l’événement accumulé
8data: still workingAjouté au tampon de données, plus un saut de ligne
9ligne videA distribué l’événement accumulé

L’analyseur lit ligne par ligne et tient trois tampons. Une ligne qui n’a rien apporté dit pourquoi.

Comment le flux se termine

Proprement. Rien ne restait dans les tampons.

Récapitulatif

Événements distribués
2
Lignes sans effet
2
Délai de reconnexion
3 000
Marque d’ordre des octets
aucune

Tout se passe dans votre navigateur. Rien de ce que vous collez n’est envoyé.

Aussi disponible en : English · Español · Português · العربية

Server-sent events : analysez le flux et voyez ce qui part

Collez un flux d’événements et obtenez ceux qui partent, le dernier identifiant à chacun, et la raison pour laquelle les autres lignes n’ont rien fait.

Que sont les server-sent events ?

Les server-sent events sont la moitié simple du temps réel sur le web : le serveur garde une réponse ouverte et y écrit des lignes de texte, le navigateur transforme chaque bloc de lignes en événement, et votre code écoute. Pas de poignée de main, pas de trames, pas de bibliothèque — une réponse au type de contenu text/event-stream et un corps fait de lignes comme data: quelque chose. C’est ce qu’emploient la plupart des API de streaming pour pousser des jetons au fil de leur génération, et le format est assez simple pour qu’on écrive des serveurs à la main.

Et l’écrire à la main est précisément là où les ennuis commencent, car le format est plus strict qu’il n’en a l’air. L’algorithme d’analyse est spécifié en entier, jusqu’à quel tampon contient quoi et quand chacun est vidé, et plusieurs de ses règles sont l’inverse de ce que la forme de la syntaxe laisse croire. Un flux peut sembler parfaitement raisonnable, ne comporter aucune erreur, et ne rien livrer du tout.

Cette page exécute cet algorithme sur ce que vous collez. Elle montre les événements qui en sortent, avec le dernier identifiant tel que l’analyseur le détiendrait à cet instant, et elle montre chaque ligne qui n’a rien apporté avec la raison. C’est en général cette seconde moitié que vous êtes venu chercher.

Comment l’utiliser

  1. Collez le corps du flux. Le corps de la réponse tel qu’il a circulé, pas les en-têtes. Les lignes peuvent se terminer par un saut de ligne, un retour chariot ou les deux — les trois sont valides, et l’un des exemples utilise chacun d’eux.
  2. Lisez les événements qui sont partis. Chacun avec son type, ses données et le dernier identifiant au moment de la distribution. Si le tableau est vide, le bloc en dessous explique quelle ligne en est responsable.
  3. Regardez les lignes sans effet. Commentaires, champs inconnus, un nom de champ à la mauvaise casse, un id contenant un caractère nul, un retry qui n’est pas un nombre, et tout bloc terminé sans distribution. Chaque ligne indique de quel cas il s’agit.

La règle sur laquelle tout le monde bute

Un événement sans données n’est pas distribué. La spécification est explicite : si le tampon de données est vide à l’arrivée d’une ligne vide, l’analyseur vide les tampons et retourne sans rien produire. Un serveur qui envoie un champ event puis une ligne vide — une façon parfaitement naturelle d’écrire un battement de cœur — ne déclenche donc aucun écouteur, ne consigne aucune erreur, et ne montre rien dans le panneau réseau sinon un flux qui a l’air de fonctionner.

Le remède est un champ data, même vide, ou un commentaire. Un data vide suffit, car l’analyseur ajoute un saut de ligne au tampon pour chaque ligne data : le tampon cesse donc d’être vide même quand la valeur l’est. Une ligne de commentaire est un deux-points suivi de n’importe quoi, et c’est la manière habituelle de maintenir une connexion ouverte : elle ne réarme le minuteur de personne et ne produit rien.

L’autre moitié de la même règle passe facilement inaperçue dans l’autre sens. Le tampon du type d’événement est vidé à chaque distribution, donc un événement sans champ event est un message. Celui du dernier identifiant ne l’est pas : la spécification dit noir sur blanc qu’il n’est pas réinitialisé, si bien qu’il conserve sa valeur jusqu’à ce que le serveur la redéfinisse. Deux tampons, côte à côte dans le même algorithme, aux durées de vie opposées. Un événement sans id hérite du précédent, et c’est cela qui repart dans l’en-tête Last-Event-ID quand la connexion tombe et que le navigateur se reconnecte.

Quatre règles plus discrètes

Exactement une espace initiale est retirée de la valeur. Une. La ligne data: bonjour et la ligne data:bonjour veulent dire la même chose, mais data: bonjour avec deux espaces en garde une. C’est un moyen courant de glisser une espace de trop dans un JSON qui refuse ensuite de s’analyser sans raison visible.

Les noms de champ sont comparés à l’identique, sans repli de casse. Data n’est pas data. Un nom avec une majuscule n’est pas une erreur et n’est signalé nulle part — c’est simplement un champ inconnu, et les champs inconnus sont ignorés. Il en va de même pour toute faute de frappe : il existe exactement quatre noms de champ, et tout le reste est écarté en silence.

Un id dont la valeur contient un caractère nul est ignoré en entier. Ni tronqué au nul, ni vidé : le tampon garde ce qu’il avait, si bien que l’événement suivant hérite de l’ancien identifiant. Et un retry ne s’applique que si sa valeur est faite uniquement de chiffres, ce qui exclut un nombre négatif, un décimal, et tout ce qui traîne une unité.

Enfin, un flux qui s’arrête en plein événement perd cet événement. La spécification dit qu’à la fin toute donnée en attente doit être jetée : un bloc avec une ligne data mais sans ligne vide derrière n’arrive donc jamais. Cet outil distingue ce cas de celui d’un flux qui s’arrête en pleine ligne, où les derniers caractères ne sont jamais devenus une ligne et n’ont même pas été regardés.

Ce que cet outil ne fait pas

Il ne se connecte à rien. Vous collez un corps ; la page le lit. Pour capturer un vrai flux, le panneau réseau de votre navigateur affiche la réponse à mesure qu’elle arrive, et un client HTTP en ligne de commande l’imprime au fil de l’eau.

Il lit un flux complet et non un flux vivant, ce qui rend un cas différent d’un vrai client. Un flux se terminant par un retour chariot isolé n’a ici aucune ambiguïté, puisqu’il n’y a rien après ; un analyseur en flux recevant les mêmes octets doit retenir ce retour chariot au cas où le morceau suivant commencerait par un saut de ligne, les deux ensemble ne formant qu’une seule fin de ligne. Les deux comportements sont corrects pour ce qu’ils sont.

Il ne vérifie pas non plus que vos données sont du JSON valide, ni quoi que ce soit d’autre. Le format transporte du texte et se désintéresse de ce que ce texte signifie — ce qu’il vaut la peine de retenir, car un champ data réparti sur plusieurs lignes est recollé avec des sauts de ligne entre les morceaux, et c’est une façon licite d’envoyer un JSON mis en forme que beaucoup de serveurs écrits à la main produisent par accident.

Pourquoi est-ce gratuit ?

Lire des lignes dans une chaîne, votre navigateur le fait instantanément. Aucun serveur n’intervient, il n’y a donc rien à facturer ni de compte à créer.

Rien n’est envoyé. Le flux que vous collez reste dans cet onglet.