10. Écouteur de flux d'événements
Se connecte à fil d'actualités (port 10020) et affiche les événements système, avec un filtrage facultatif par niveau, par partie du nom et par exclusion. Lecture seule : aucun profil de session et aucune commande envoyée.
Ce que vous apprendrez :
- S'abonner aux événements WebSocket (port
10020) en tant qu'observateur passif - Analyser un événement JSON —
level,name,category,data,message - Filtrer par niveau de gravité minimal
- Correspondance de noms à l'aide de caractères génériques et exclusion
- Utilisez ce tutoriel pour évaluer les performances de la boucle de contrôle en parallèle avec n'importe quel autre tutoriel
Déroulement
- Analyser les options de l'interface en ligne de commande (CLI) (
--level,--name,--exclude,--no-hide-rate,--port). - Se connecter à
ws://localhost:10020(le fil d'actualités) — aucun profil de session n'est envoyé, puisqu'il s'agit d'un observateur en lecture seule. - Pour chaque message entrant, analyser l'événement JSON et appliquer les filtres :
- Ignorer le message si
levelest inférieur au seuil minimal de gravité. - Si des motifs
--namesont fournis, ignorer le message sauf si l'un d'entre eux correspond (ànameseul ou àcategory/name). - Si un motif
--excludecorrespondre, ignorer le message.
- Ignorer le message si
- Afficher les événements sélectionnés avec leur niveau, leur nom complet, le message facultatif et la charge utile
datafacultatif.
Paramètres
| Option | Valeur par défaut | Rôle |
|---|---|---|
--port | 10020 | Port du canal des événements |
-l, --level | info | Gravité minimale — l'une des valeurs info, notice, warning, error, critical, panic |
-n, --name | (aucune) | N'afficher que les événements correspondant au motif (glob, répétable) |
-x, --exclude | (aucune) | Masquer les événements correspondant au motif (glob, répétable) |
--no-hide-rate | false | Inclure les événements system-rate-report (masqués par défaut, car ils parlent beaucoup) |
Lancez n'importe quel tutoriel (04-hello-floor, 05-position-control, 06-combined...) dans un terminal, et le gestionnaire d'événements avec --no-hide-rate dans un autre. L'événement system-rate-report contient la fréquence de tick effective de l'appareil : comparez les variantes Python / C++ nlohmann / C++ Glaze d'un même tutoriel pour observer la surcharge liée à la sérialisation sur une boucle de contrôle d'environ 4 kHz.
# Terminal 1 — pick a variant
./04-haply-inverse-hello-floor # C++ nlohmann
./04-haply-inverse-hello-floor-glz # C++ Glaze
python 04-haply-inverse-hello-floor.py # Python
# Terminal 2 — watch the rate
./10-haply-inverse-events --no-hide-rate
Champs d'État lus
Chaque message entrant correspond à un seul événement :
level— gravité sous forme de chaîne (info...panic)name— nom de l'événement (par ex.device-connected,system-rate-report)category— catégorie (par ex.device,session,system)message— chaîne lisible facultativedata— charge utile JSON imbriquée facultative (la structure dépend de l'événement)
Catalogue complet des événements : Événements et surveillance.
Envoi / réception
Abonnement passif — individuel recv() est utilisée ; rien n'est renvoyé. Les trois variantes implémentent le même pipeline de filtrage ; la partie la plus spécifique à l'API Inverse est la structure de l'événement.
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocket est la forme la plus courte de la boucle de réception seule.
async with websockets.connect(uri) as websocket:
async for msg in websocket:
try:
event = json.loads(msg)
except json.JSONDecodeError:
continue
if accept_event(event, min_level_index, name_patterns, exclude_patterns):
print(format_event(event))
Modèle de rappel libhv — onmessage s'exécute sur le thread d'E/S ; le thread principal se bloque en attendant une ENTRÉE. Les événements sont traités comme des objets JSON non typés — chaque champ est lu via .value(...) avec une valeur par défaut.
ws.onmessage = [&](const std::string &msg) {
json event;
try { event = json::parse(msg); } catch (...) { return; }
if (accept_event(event, opts.min_level, opts.name_patterns, opts.exclude_patterns))
print_event(event);
};
ws.open("ws://localhost:10020");
while (std::cin.get() != '\n') {} // block main thread
Les champs d'événement connus sont mappés sur une structure event_data typée. Le champ data reste de type glz::raw_json_view, afin que des charges utiles imbriquées arbitraires (qui dépendent de l'événement) puissent être transmises telles quelles, sans qu'il soit nécessaire de définir un schéma complet.
// Struct model — known fields typed, nested `data` kept as raw JSON
struct event_data {
std::string level;
std::string name;
std::string category;
std::string message;
glz::raw_json_view data{};
};
// Send / receive
ws.onmessage = [&](const std::string &msg) {
event_data event{};
if (glz::read<glz_settings>(event, msg)) return; // drop malformed
if (accept_event(event, opts.min_level, opts.name_patterns, opts.exclude_patterns))
print_event(event);
};
ws.open("ws://localhost:10020");
while (std::cin.get() != '\n') {} // block main thread
Le tutoriel n° 10 est également installé localement avec le SDK — consultez tutorials/10-haply-inverse-events/ dans le répertoire d'installation du service.
Source : Python · C++ · C++ Glaze
Voir aussi : Événements et surveillance · Protocole WebSocket