10. Écouteur de flux d'événements
Chaîne dédiée aux événements(Port) 10020) et génère des événements système après avoir appliqué un filtrage au choix en fonction du niveau, du modèle de nom et des conditions d'exclusion. Comme il s'agit d'un mode lecture seule, aucun profil de session ni aucune commande n'est envoyé.
Ce que vous apprendrez dans ce tutoriel :
- En tant qu'observateur passifÉvénement WebSocket(Port)
10020) s'abonner à - Événement JSONAnalyse de —
level,name,category,data,message - Filtrage selon le niveau de gravité le plus bas
- Correspondance et 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) sera analysé. ws://localhost:10020(Chaîne dédiée aux événements) à laquelle il se connecte. Comme il fonctionne en tant qu'observateur en lecture seule, il n'envoie pas de profil de session.- Pour chaque message reçu, le JSON de l'événement est analysé et un filtre est appliqué :
levelSi celle-ci est inférieure au niveau de gravité minimal, elle sera supprimée.--nameSi un motif est spécifié, la requête est rejetée si elle ne correspond à aucun d'entre eux (nameseul oucategory/name(et les compare).--excludeSi l'un des modèles correspond, la donnée est rejetée.
- Les événements restants, avec leur niveau, leur nom de modificateur, un message (facultatif), un (facultatif)
dataIl s'affiche avec la charge utile.
Paramètres
| drapeau | Par défaut | Utilisation |
|---|---|---|
--port | 10020 | Port du canal d'événements |
-l, --level | info | Niveau de gravité le plus faible.info,notice,warning,error,critical,panic l'un ou l'autre |
-n, --name | (aucun) | Afficher uniquement les événements correspondant au motif (glob, plusieurs motifs possibles) |
-x, --exclude | (aucun) | Masquer les événements correspondant à un motif (glob, plusieurs motifs peuvent être spécifiés) |
--no-hide-rate | false | system-rate-report Inclure les événements (masqués par défaut — car ils génèrent beaucoup de bruit) |
Exécutez n'importe quel tutoriel (04-hello-floor, 05-position-control, 06-combined...) dans un terminal, puis dans un autre terminal, --no-hide-rate Veuillez exécuter l'écouteur d'événement spécifié.system-rate-report L'événement inclut la fréquence de mise à jour effective du périphérique. Comparez les versions Python/C++ de nlohmann et C++ de Glaze issues du même tutoriel afin de vérifier la surcharge liée à la sérialisation dans une boucle de contrôle à 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 reçu correspond à un événement :
level— Niveau de gravité de la chaîne 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— Une chaîne de caractères arbitraire, lisible par l'utilisateurdata— Une charge utile JSON imbriquée au choix (le format varie selon l'événement)
Pour consulter la liste complète des événements, veuillez vous reporter à la section « Événements et surveillance ».
Envoyer / Recevoir
Pour un abonnement passif,recv() Elle utilise uniquement cette fonction et ne renvoie rien. Les trois variantes implémentent toutes le même pipeline de filtrage. La structure des objets événementiels constitue un point particulier à l'API Inverse.
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocket C'est la façon la plus concise d'écrire une boucle de réception uniquement.
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))
Il s'agit du mécanisme de rappel de libhv.onmessage Il s'exécute dans un thread d'E/S, tandis que le thread principal attend la pression de la touche ENTER. L'événement est traité comme un JSON sans type, et chaque champ est associé à une valeur par défaut. .value(...) est lu.
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énements connus sont de type event_data Il est mappé sur la structure.data Les champs sont glz::raw_json_view Comme elles sont conservées telles quelles, il est possible de transférer des charges utiles imbriquées arbitraires (qui varient selon les événements) sans avoir à définir de 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, tutorials/10-haply-inverse-events/ Veuillez vérifier.
Source : Python · C++ · C++ Glaze
Voir aussi : Événements et surveillance · Protocole WebSocket