使用godbus导出具有父子层级的DBus对象时仅单个可访问问题
问题根因
- DBus的对象路径采用树状结构组织,父节点的内省响应必须显式声明所有直接关联的子节点路径,客户端才能顺着路径树定位到深层的对象。
- 当前给父路径
/a/b/c编写的内省XML,只列出了自身实现的a.b.c.Ping接口,完全没有提及子路径/a/b/c/d的存在。客户端查询/a/b/c的内省结果时,根本不知道节点下还有另一个可访问的对象,自然会在两个路径存在层级重叠时,表现为仅能访问到其中一个对象。 - godbus库不会自动为已导出的层级路径补全内省响应里的子节点声明,手动编写的静态内省XML如果漏了子节点条目,哪怕代码层面已经成功导出子对象,客户端也会因为路由不到正确的路径触发访问失败。
- 单独导出单个对象、或是两个对象路径完全无层级重叠时,不存在树状结构的父节点内省声明要求,所以运行表现完全正常。
修复方案
- 修改父路径
/a/b/c对应的内省XML,在根<node>标签内部补充子节点的声明条目,也就是加上<node name="d"/>,明确告知客户端/a/b/c下存在名为d的直接子节点。 - 子路径
/a/b/c/d本身没有再嵌套的下级对象,当前编写的内省内容不需要改动,保持原有逻辑即可。 - 修改后的父节点内省字符串示例:
const introP = ` <node> <!-- 声明直接子节点 --> <node name="d"/> <interface name="a.b.c.Ping"> <method name="Ping"> <arg direction="out" type="s"/> </method> </interface> ` + introspect.IntrospectDataString + `</node> `
- 如果后续需要维护更多层级的嵌套路径,没必要手动逐行补写静态的子节点声明,可以自定义内省逻辑,遍历同连接下导出的所有对象路径,动态生成匹配的子节点列表,减少后续维护成本。
内容的提问来源于stack exchange,提问作者Xaqron
相关产品推荐
相关产品推荐

