Open*** v3 Dbus 客户端未接收到所有信号
Posted
技术标签:
【中文标题】Open*** v3 Dbus 客户端未接收到所有信号【英文标题】:Open*** v3 Dbus client not receiving all signals 【发布时间】:2021-09-20 00:52:47 【问题描述】:我正在为 Linux Mint/Cinnamon 编写一个 Applet 来管理 Open*** v3 连接。
为了避免可能导致 DE 卡顿或冻结的同步调用,我正在使用 GJS 提供的 Gio
和 GLib
库编写一个简单的 DBus 客户端。这允许异步的、部分事件驱动的方法,并且应该避免任何令人讨厌的副作用。这是我第一次使用这些技术,但 Open*** DBus API 是 pretty well documented,Gio and GLib 的 API 文档也不错。
我遇到的问题是信号订阅,特别是net.open***.v3.sessions
服务发布的StatusChange
信号。每当建立、暂停、恢复或关闭连接时,都会发布一堆这些信号。大多数信号都是由我订阅的听众接收的,但不是全部。特别是,我没有收到session closed
信号。
使用dbus-monitor
命令行工具,可以看到建立连接(7个信号)然后关闭(2个信号)时发布的所有StatusChange
信号:
$ sudo dbus-monitor --system "type='signal',interface='net.open***.v3.sessions',member='StatusChange'"
...
// Connect:
signal time=1625847543.107244 sender=:1.891 -> destination=:1.892 serial=2745 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 3
uint32 27
string "session_path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49, backend_pid=42584"
signal time=1625847543.116395 sender=:1.891 -> destination=:1.892 serial=2762 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 3
uint32 17
string "session_path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49 backend_busname=net.open***.v3.backends.be42585 backend_path=/net/open***/v3/backends/session"
signal time=1625847543.117286 sender=:1.891 -> destination=(null destination) serial=2764 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 2
uint32 2
string "config_path=/net/open***/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232"
signal time=1625847543.638519 sender=:1.891 -> destination=(null destination) serial=2775 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 2
uint32 2
string "config_path=/net/open***/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232"
signal time=1625847543.638533 sender=:1.891 -> destination=(null destination) serial=2776 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 2
uint32 6
string ""
signal time=1625847543.735357 sender=:1.891 -> destination=(null destination) serial=2777 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 2
uint32 6
string ""
signal time=1625847543.974784 sender=:1.891 -> destination=(null destination) serial=2778 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 2
uint32 7
string ""
// Disconnect:
signal time=1625847646.846790 sender=:1.891 -> destination=:1.892 serial=2834 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 3
uint32 28
string "Session closed"
signal time=1625847646.848262 sender=:1.891 -> destination=:1.892 serial=2839 path=/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49; interface=net.open***.v3.sessions; member=StatusChange
uint32 3
uint32 19
string ""
以下代码创建了一个订阅,据我所知,它应该接收与上述相同的信号。注意我在这里使用较低级别的方法来获取订阅;订阅是在全局连接上进行的,而不是通过特定对象路径的 DBusProxy
。我已经尝试了这两种方法(结果相同),但以下应该更类似于上面的dbus-monitor
命令。
subscribeToStatusChangeSignals()
this.statusChangeHandlerId = Gio.DBus.system.signal_subscribe(
'net.open***.v3.sessions',
'net.open***.v3.sessions',
'StatusChange',
null,
null,
Gio.DBusSignalFlags.NONE,
this._handleGlobalStatusChangeSignal
);
_handleGlobalStatusChangeSignal(connection, sender, path, iface, signal, params)
let container = params.deep_unpack();
let statusMajorCode = container[0];
let statusMinorCode = container[1];
let statusMajor = lookupStatusMajor(statusMajorCode); // lookup the corresponding text
let statusMinor = lookupStatusMinor(statusMinorCode); // from something resembling an enum
let message = container[2];
global.log(`Received StatusChange signal
path: [$path]
Status Major: [$statusMajorCode - $statusMajor]
Status Minor: [$statusMinorCode - $statusMinor]
Message: [$message]`
);
打开和关闭同一个连接时产生的日志:
// Connect:
Cjs-Message: 18:19:03.117: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [2 - CFG_OK]
Message: [config_path=/net/open***/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232]
Cjs-Message: 18:19:03.638: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [2 - CFG_OK]
Message: [config_path=/net/open***/v3/configuration/9dd3fa9cxb6e0x48acxaa1ex566312bea232]
Cjs-Message: 18:19:03.639: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [6 - CONN_CONNECTING]
Message: []
Cjs-Message: 18:19:03.735: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [6 - CONN_CONNECTING]
Message: []
Cjs-Message: 18:19:03.974: JS LOG: [LookingGlass/info] Received StatusChange signal
path: [/net/open***/v3/sessions/052850e7s915fs483esb3e7s3afb389a2e49]
Status Major: [2 - CONNECTION]
Status Minor: [7 - CONN_CONNECTED]
Message: []
// Disconnect:
<nada>
我注意到的一个模式是,我收到的所有信号在dbus-monitor
输出中都有一个null destination
:
... sender=:1.891 -> destination=(null destination) ...
虽然我没有收到的信号有特定的目的地:
... sender=:1.891 -> destination=:1.892 ...
大概这些是针对特定接收者的直接信号,而不是向所有感兴趣的订阅者广播的信号,但我在文档中的任何地方都没有发现这一点。
所以问题是,为什么我会收到一些信号,但不是全部?这是设计使然,还是Gio
的问题,或者(更有可能)是我使用它的问题?
【问题讨论】:
【参考方案1】:经过进一步挖掘,这种行为似乎是设计使然——携带目标值的信号被视为单播消息。预定收件人以外的订阅者只有在配置为eavesdrop
时才会收到此类消息。 dbus-monitor
大概就是这种情况。
来源:DBus Specification (Message Routing)
【讨论】:
以上是关于Open*** v3 Dbus 客户端未接收到所有信号的主要内容,如果未能解决你的问题,请参考以下文章