10. 事件流监听器
登录到 活动频道 (端口 10020) 并显示系统事件,可选按级别、名称模式和排除条件进行筛选。只读模式——不创建会话配置文件,也不发送任何命令。
您将学到:
- 订阅 WebSocket 事件 (端口
10020) 以被动观察员的身份 - 分析一个 JSON 事件 —
level,name,category,data,message - 按最低严重程度筛选
- 使用通配符进行名称匹配以及排除
- 请结合本教程与任何其他教程,评估并行控制循环的性能
流程
- 分析 CLI 选项(
--level,--name,--exclude,--no-hide-rate,--port). - 登录到
ws://localhost:10020(le 活动频道) — 由于这是一个只读观察者,因此不会发送任何会话配置文件。 - 对于每条传入的消息,分析 JSON 事件并应用过滤器:
- 如果出现以下情况,请忽略该消息:
level低于最低严重程度级别。 - 如果存在理由
--name如果提供了多个选项,则忽略该消息,除非其中一个与(name独自一人或与……category/name). - 如果有一个理由
--exclude若不匹配,则忽略该消息。
- 如果出现以下情况,请忽略该消息:
- 显示已筛选的事件及其级别、全称、可选消息和有效载荷
data兼性。
参数
| 选项 | 默认值 | 角色 |
|---|---|---|
--port | 10020 | 活动频道端口 |
-l, --level | info | 最低限度的庄重——价值观之一 info, notice, warning, error, critical, panic |
-n, --name | (无) | 仅显示符合模式(全局、可重复)的事件 |
-x, --exclude | (无) | 隐藏与该模式(全局、可重复)匹配的事件 |
--no-hide-rate | false | 包含活动 system-rate-report (默认隐藏,因为内容过多) |
评估控制回路的性能
在终端中运行任意一个教程(04-hello-floor、05-position-control、06-combined...),事件监听器将通过 --no-hide-rate 在另一个中。该事件 system-rate-report 包含设备的有效时钟频率:请比较同一教程中 Python / C++ nlohmann 和 C++ Glaze 版本,以观察在约 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
阅读过的州冠军
每条传入的消息对应一个事件:
level— 以链状形式存在的引力(info……panic)name— 活动名称(例如device-connected,system-rate-report)category— 类别(例如device,session,system)message— 可选的可读字符串data— 可选的嵌套 JSON 有效载荷(结构取决于事件)
活动完整目录:活动与监控。
发送/接收
被动订阅——仅此一项 recv() 被调用;不会返回任何内容。这三种变体都实现了相同的过滤管道;其中与 Inverse API 最相关的部分是事件的结构。
- Python
- C++ (nlohmann)
- C++ (Glaze)
async for msg in websocket 是仅包含接收循环的最简形式。
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))
libhv 回调模型 — onmessage 在 I/O 线程上执行;主线程在等待输入时被阻塞。事件被视为无类型的 JSON —— 每个字段都是通过 .value(...) 并带有默认值。
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
已知的事件字段被映射到一个结构上 event_data 类型化。该字段 data 类型余量 glz::raw_json_view, 以便能够原样传输任意嵌套的有效载荷(取决于事件),而无需定义完整的架构。
// 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
随附 SDK 安装程序
教程 10 也随 SDK 一起本地安装了——请参阅 tutorials/10-haply-inverse-events/ 在服务安装目录中。
另请参阅: 事件与监视·WebSocket 协议