网络拓扑感知
可用性:两个变体(Full / Tiny)均支持,接口与用法完全一致。
本特性让 OnePath 应用能够发现统一逻辑网络的拓扑:网络中有哪些节点、各节点承载了哪些 服务、节点之间通过什么传输(tcp / udp / serial / …)相连、是否走本地共享内存(SHM)。 它可作为监测、运维与可视化的数据来源,例如绘制节点 / 服务关系图。整个能力为纯库内实现, 无需任何中心服务器。
概念
OnePath 用 节点(node) 表示网络中的一个通信实体,以 节点 ID 唯一标识,并带有 角色:ONEPATH_ROUTER / ONEPATH_PEER / ONEPATH_CLIENT。每个节点可承载多个 服务(以 keyexpr 标识的发布者 / 订阅者 / 应答器 / 存活令牌)。
拓扑感知分两层:
本地视图(第 1 层):
onepath_topology_local()给出本节点的「一跳」局部视图——它 直接相连的邻居节点(节点 ID、角色、连接所用传输与地址、是否共享内存)以及本节点自己 承载的服务清单。全局聚合(第 2 层):每个节点运行一个 拓扑 agent 对外提供本节点的局部视图; 监测端调用
onepath_topology_snapshot()一次性收集网络中所有节点的局部视图,合并去重 为一张 全局拓扑图(节点 + 边 + 边上的传输标签 + 各节点服务)。
中继节点务必运行 agent
单个节点只能看到自己的直接连接。要得到全局图,需要各节点都运行 agent。因此承担中继的 节点(router / peer)务必运行 agent——这样即使它下游的纯客户端自身没有运行 agent,也会 作为该中继的邻居出现在全局图中。
API 速览
int onepath_topology_local(onepath_session_t s, onepath_topo_local_t *out);
void onepath_topology_local_free(onepath_topo_local_t *local);
int onepath_topology_agent_start(onepath_session_t s);
void onepath_topology_agent_stop(onepath_session_t s);
int onepath_topology_snapshot(onepath_session_t s, onepath_topo_graph_t *out, uint64_t timeout_ms);
void onepath_topology_graph_free(onepath_topo_graph_t *graph);| 接口 | 作用 |
|---|---|
onepath_topology_local(s, &local) | 获取本节点一跳局部视图;用毕 onepath_topology_local_free |
onepath_topology_agent_start(s) | 启动本节点拓扑 agent(对外提供本节点局部视图);幂等 |
onepath_topology_agent_stop(s) | 停止 agent(onepath_close 也会自动停止) |
onepath_topology_snapshot(s, &graph, timeout_ms) | 聚合全局拓扑图;timeout_ms=0 默认 5000ms;用毕 onepath_topology_graph_free |
onepath_topology_local / _agent_start / _agent_stop 在不支持该能力的运行环境下返回 ONEPATH_ERR_UNSUPPORTED(接口始终存在、可正常编译链接),应用据此优雅降级即可。
服务归类:OnePath 在每次成功声明发布者 / 订阅者 / 应答器 / 存活令牌时,自动把其 keyexpr 登记到本会话,agent 据此上报「本节点承载了哪些服务」(OnePath 内部使用的 keyexpr 不会 出现在服务清单中)。
数据结构
typedef struct { /* onepath_topo_link_t:一条物理链路 */
char proto[16]; /* 传输协议 (tcp/udp/serial/...) */
char dst[128]; /* 远端 locator (协议+地址) */
char src[128]; /* 本端 locator */
uint16_t mtu; int reliable; int is_streamed;
} onepath_topo_link_t;
typedef struct { /* onepath_topo_neighbor_t:一个直连邻居 */
char zid[33]; int whatami; int is_shm; int is_multicast;
onepath_topo_link_t *links; size_t num_links;
} onepath_topo_neighbor_t;
typedef struct { /* onepath_topo_local_t:本节点 1-hop 视图 */
char self_zid[33]; int self_whatami;
onepath_topo_neighbor_t *neighbors; size_t num_neighbors;
const char **services; size_t num_services;
} onepath_topo_local_t;
typedef struct { /* onepath_topo_node_t:全局图中的节点 */
char zid[33]; int whatami; const char **services; size_t num_services;
} onepath_topo_node_t;
typedef struct { /* onepath_topo_edge_t:全局图中的边 */
char a_zid[33]; char b_zid[33]; char proto[16]; int is_shm;
} onepath_topo_edge_t;
typedef struct { /* onepath_topo_graph_t:聚合后的全局图 */
onepath_topo_node_t *nodes; size_t num_nodes;
onepath_topo_edge_t *edges; size_t num_edges;
} onepath_topo_graph_t;用法示例
onepath_session_t s;
onepath_open_peer(&s);
/* 声明业务服务(会自动登记,供拓扑归类) */
onepath_publisher_t pub;
onepath_declare_publisher(s, &pub, "demo/sensor/temp", NULL);
/* 启动 agent,让本节点对外可见 */
onepath_topology_agent_start(s);
/* 查询全局拓扑图 */
onepath_topo_graph_t g;
if (onepath_topology_snapshot(s, &g, 2000) == ONEPATH_OK) {
for (size_t i = 0; i < g.num_nodes; i++)
printf("node %s, %zu services\n", g.nodes[i].zid, g.nodes[i].num_services);
for (size_t i = 0; i < g.num_edges; i++)
printf("edge %s <-%s%s-> %s\n", g.edges[i].a_zid, g.edges[i].proto,
g.edges[i].is_shm ? "/shm" : "", g.edges[i].b_zid);
onepath_topology_graph_free(&g);
}配套示例程序 onepath_topology_map 给出完整可运行版本,并演示 client + server + peer + 监测节点的端到端多进程拓扑打印。
创建 / 销毁配对
| 创建 | 销毁 |
|---|---|
onepath_topology_agent_start | onepath_topology_agent_stop(onepath_close 亦自动停止) |
onepath_topology_local(out 参数) | onepath_topology_local_free |
onepath_topology_snapshot(out 参数) | onepath_topology_graph_free |
边界与说明
- 全局图的完整性取决于哪些节点运行了 agent;只有运行 agent 的节点(及其直接邻居)会出现 在图中。
- 邻居的地址取自各节点自身的监听端点,反映「如何到达该节点」,而非多跳路由路径。
- 边上的
is_shm表示两端是否已启用本地共享内存传输,可作为「同节点最优路径」等上层能力 的判据。它也可用于观测 同机自动 SHM 是否生效:同机邻居is_shm为1, 跨机为0(同机探测失败会自动回退普通网络)。 - 跨网段发现受底层发现机制约束(组播发现限本网段;跨网段需经中继节点并在其上运行 agent)。