10. Écouteur de flux d'événements
Chaîne des événements(Port 10020) afin d'afficher les événements système filtrés de manière sélective selon leur niveau, leur modèle de nom et leurs conditions d'exclusion. Comme il s'agit d'un mode lecture seule, aucun profil de session n'est envoyé et aucune commande n'est transmise.
Contenu pédagogique :
- En tant qu'observateur passif Événement WebSocket(Port
10020) S'abonner - JSON d'événement Analyse syntaxique —
level,name,category,data,message - Filtrer selon le niveau de gravité minimal
- Appliquer la correspondance et l'exclusion de noms à l'aide de caractères génériques
- Utilisez ce tutoriel en complément d'autres tutoriels pour évaluer les performances des boucles de contrôle
Flux de travail
- Options de ligne de commande (
--level,--name,--exclude,--no-hide-rate,--port) est analysé. ws://localhost:10020(Chaîne des événements) s'y connecte. Comme il s'agit d'un observateur en lecture seule, il ne transmet pas de profil de session.- Pour chaque message reçu, nous analysons l'objet JSON de l'événement et appliquons les filtres suivants :
levelSi la gravité est inférieure à ce seuil minimum, la donnée est rejetée.--nameSi un motif a été défini, l'un des motifs (nameseul oucategory/name) ne correspond pas, il est ignoré.--excludeSi ne serait-ce qu'un seul des motifs correspond, l'élément est écarté.
- Les événements ayant passé le filtre, avec leur niveau, leur nom complet, un message facultatif, un
dataL'affiche avec la charge utile.
Paramètres
| drapeau | Valeur par défaut | Utilisation |
|---|---|---|
--port | 10020 | Port du canal d'événements |
-l, --level | info | Gravité minimale — info, notice, warning, error, critical, panic l'un d'entre eux |
-n, --name | (aucun) | Afficher uniquement les événements correspondant au motif (glob, répétition possible) |
-x, --exclude | (aucun) | Masquer les événements correspondant à un motif (glob, répétition possible) |
--no-hide-rate | false | system-rate-report Événements inclus (masqués par défaut — volume de données très important) |
Lancez un tutoriel au choix (04-hello-floor, 05-position-control, 06-combined...) dans un terminal, puis dans un autre terminal, --no-hide-rate Exécutez l'écouteur d'événements en spécifiant les options. system-rate-report Cet événement inclut la fréquence de rafraîchissement effective du dispositif. En comparant cette valeur entre les versions Python/C++ de nlohmann et C++ de Glaze du même tutoriel, on constate une surcharge de sérialisation d'environ 4 kHz dans la boucle de contrôle.
# 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
Champ « État de lecture »
Chaque message reçu correspond à un événement :
level— Niveau de gravité des chaînes de caractères (info...panic)name— Nom de l'événement (par exemple :device-connected,system-rate-report)category— Catégorie (par exemple :device,session,system)message— Chaîne de caractères lisible par l'utilisateur (facultative)data— Charge utile JSON imbriquée (facultative ; la structure varie selon l'événement)
Pour consulter la liste complète des événements, reportez-vous à la section « Événements et surveillance».
Émission / Réception
Comme il s'agit d'un abonnement manuel, recv()Elle ne fait que consommer des données et ne renvoie rien. Les trois variantes implémentent toutes le même pipeline de filtrage ; parmi les aspects spécifiques à l'API Inverse, il convient de noter la structure des objets événementiels.
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocketC'est la forme la plus concise d'une boucle en lecture 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 — onmessageIl s'exécute dans un thread d'E/S, tandis que le thread principal est bloqué en attendant la pression de la touche ENTER. L'événement est considéré comme un JSON sans type, et chaque champ est associé à une valeur par défaut, ainsi que .value(...)On lit :
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 de type event_data Il est mappé à une structure. data Le champ est glz::raw_json_viewComme il est conservé tel quel, il est possible de transmettre une charge utile imbriquée arbitraire, qui varie en fonction de l'événement, sans avoir à définir le 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 10 est également installé localement avec le SDK. Dans le répertoire d'installation du service, sous le dossier tutorials/10-haply-inverse-events/Veuillez consulter cette page.
Code source : Python · C++ · C++ Glaze
Documents associés : Événements et surveillance · Protocole WebSocket