dbus 如何重新连接到新的会话总线守护进程

Posted

技术标签:

【中文标题】dbus 如何重新连接到新的会话总线守护进程【英文标题】:dbus how to reconnect to a new session bus daemon 【发布时间】:2014-09-21 07:21:40 【问题描述】:

据我了解,如果环境定义了两个变量,例如,dbus 用户将连接到会话总线守护进程:

DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-1cAnv4I,guid=3a453c40b5034f
DBUS_SESSION_BUS_PID=102

如果守护进程停止并且我们通过 dbus-launch 启动一个新的守护进程,我们将获得环境的新值。在这种情况下,如何在不重新启动的情况下将新值传播到正在运行的用户进程中?

【问题讨论】:

【参考方案1】:

重启后获取地址的一种方法是查询对应的X11属性:

dbus-daemon 设置_DBUS_SESSION_BUS_SELECTION_[hostname]_[uuid] 选择所有者的_DBUS_SESSION_BUS_ADDRESS 属性(uuid 是/var/lib/dbus/machine-id 的内容)。这是我用来读取 this 值的代码:https://github.com/sidorares/node-dbus/blob/master/lib/address-x11.js

【讨论】:

我没有运行 X。我需要一种方法来将总线地址更新到正在运行的总线用户进程中,而无需重新启动它。感谢您提供可能对 x 用户有用的解决方案。【参考方案2】:

重新连接到新的 dbus 守护进程的逻辑应该涉及一些组件和事件:

一个总线监视器,它告诉应用程序总线是否仍在运行、关闭或重新启动。

当总线重新启动时,新的总线地址将被发送到应用程序。

响应宕机和重启事件的应用程序:

如果总线关闭或重新启动,请关闭所有内容并返回到调用 dbus_bus_get() 之前的总线循环开始。 如果总线出现故障,请等待总线重新启动。 如果总线重新启动,将进程环境变量DBUS_SESSION_BUS_ADDRESS修改为新的dbus地址,然后调用dbus_bus_get()继续新的总线循环。

如果您阅读dbus/dbus_bus.c 中的代码并遵循dbus_bus_get() -> internal_bus_get() -> init_connections_unlocked() 中的功能,您可能会看到上面的逻辑是您可以做的。或者您可能会看到做同样事情的其他方法。如果您知道其他方法或有其他想法,请发表评论。

编辑:用更多细节验证方法:

dbus_bus_get() 之后,调用dbus_connection_set_exit_on_disconnect(conn,FALSE) 以便在dbus 守护程序断开连接后应用程序将继续运行。 添加一个调用dbus_connection_read_write(conn,0) 的哑信号接收器。如果 dbus 连接丢失,它会返回一个FALSE。这用于决定何时关闭 dbus 循环。尽管连接已关闭,但使用 dbus_connection_pop_message(conn) 排空消息队列。 通过dbus_connection_unref(conn) 然后dbus_shutdown() 关闭dbus 周期。如果未关闭,则对 dbus_bus_get() 的调用将不会使用新的环境变量。 使用setenv(char * name, char * value) 设置会话总线地址。

【讨论】:

以上是关于dbus 如何重新连接到新的会话总线守护进程的主要内容,如果未能解决你的问题,请参考以下文章

连接到示例 DBus 守护程序的 C# 程序总是得到“访问被拒绝:DBus.BusObject”

Linux DBus 通信

DBUS-“服务”和“总线名称”的区别

dbus-发送到远程机器

连接到不同计算机上的会话 DBus

登录ubuntu之前如何在python守护进程中使用DBUS