10. 事件流监听器
连接到 事件频道 (端口 10020) 并打印系统事件,支持按级别、名称模式和排除项进行可选过滤。只读模式——不创建会话配置文件,不发送任何命令。
您将学到:
- 订阅 WebSocket 事件 (端口
10020) 作为旁观者 - 语法分析 事件 JSON —
level,name,category,data,message - 按最低严重性级别筛选
- 通配符名称匹配与排除
- 使用本教程与其他教程一起对控制回路进行性能测试
工作流程
- 解析 CLI 参数 (
--level,--name,--exclude,--no-hide-rate,--port). - 连接到
ws://localhost:10020(该 事件频道) — 由于这是一个只读观察者,因此不会发送任何会话配置文件。 - 对于每条传入的消息,解析事件 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 线程上运行;主线程在 ENTER 处阻塞。事件被视为无类型的 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 协议