10. 事件流监听器
与……连接 活动频道 (港口 10020) 并输出系统事件,可选按严重程度、名称模式和排除项进行过滤。仅读取——不创建会话配置文件,不会发送任何命令。
您将学到:
- 订阅 事件-WebSocket (港口
10020) 作为旁观者 - 解析 Event-JSON —
level,name,category,data,message - 按最低严重程度筛选
- 使用占位符和排除条件进行名称匹配
- 将本教程与任意其他教程结合使用,对控制回路进行基准测试
流程
- 解析 CLI 标志 (
--level,--name,--exclude,--no-hide-rate,--port). - 链接至
ws://localhost:10020herstellen (der 活动频道) — 由于该观察者仅具有只读权限,因此不会发送会话配置文件。 - 对每条传入的消息解析其事件 JSON 并应用过滤器:
- 在以下情况下应予以驳回:
level低于最低严重程度。 - Wenn
--name-如果列出了以下情况,且均不适用,则予以驳回(无论是违反name独自一人或对抗category/name). - 如果一个
--exclude-如果符合该模式,则弃用。
- 在以下情况下应予以驳回:
- 剩余事件,包含严重程度、限定名称、可选消息和可选
data-输出有效载荷。
参数
| 旗帜 | 标准 | Zweck |
|---|---|---|
--port | 10020 | 活动频道的端口 |
-l, --level | info | 最低严重程度——其中之一 info, notice, warning, error, critical, panic |
-n, --name | (keiner) | 仅显示符合该模式的事件(通配符,可重复) |
-x, --exclude | (keiner) | 隐藏符合该模式的事件(全局、可重复) |
--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 有效载荷(格式取决于事件)
完整事件目录:事件与监控。
发送 / 接收
Passives 订阅 — 仅 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
教程 10 也会随 SDK 一起本地安装——您可以在以下位置找到它: tutorials/10-haply-inverse-events/ 位于该服务的安装目录中。
相关主题: 事件与监控·WebSocket 协议