【发布时间】:2017-06-28 17:30:24
【问题描述】:
我想知道直接通过低级 C API 调用 dbus_connection_send_with_reply 使用 D-Bus 是否保证消息传递?
更具体地说,它是否保证消息的单个实例被传递到目标,或者如果失败则返回错误回复?
我了解接收应用程序可能不会对某个方法发出回复,在这种情况下,D-Bus 将在超时后返回错误。但是,D-Bus 协议是否涵盖了所有其他潜在故障?
【问题讨论】:
我想知道直接通过低级 C API 调用 dbus_connection_send_with_reply 使用 D-Bus 是否保证消息传递?
更具体地说,它是否保证消息的单个实例被传递到目标,或者如果失败则返回错误回复?
我了解接收应用程序可能不会对某个方法发出回复,在这种情况下,D-Bus 将在超时后返回错误。但是,D-Bus 协议是否涵盖了所有其他潜在故障?
【问题讨论】:
tl;博士:
永远无法保证交货。但是,即使消息未送达,您也可能会收到这样的错误回复。
如果您使用DBUS_TIMEOUT_INFINITE,您可能会一直等待回复。如果函数调用返回FALSE,则不会有回复。否则,您将得到一个。
我是 D-Bus(消息传递协议规范)和 dbus(D-Bus 的参考实现)的上游维护者。
术语:调用dbus_connection_send_with_reply() 的进程是客户端,期望回复的进程是服务。通常在两者之间会有一个dbus-daemon,尽管在特殊情况下可以直接连接到服务(如果您正在这样做,那么您应该已经知道您正在这样做)。
一般来说,API 保证如果dbus_connection_send_with_reply() 成功(返回TRUE),您将看到一个回复,可以是成功返回(仅当消息已传递)或错误(无论消息是否已传递,都可能发生)。如果由于内存不足或其他病理状况而失败(返回FALSE),您将完全看不到任何回复。为了确保这一点,实施过程花费了相当长的时间。
在dbus_connection_send_with_reply() 返回之前,它会预先分配在调用超时时您将收到的综合错误消息;如果失败,则不发送消息并且dbus_connection_send_with_reply() 失败。因此,即使dbus-daemon 或传输将真实(成功或错误)回复丢弃在地板上,您最终也会收到超时错误消息。 (参考:git grep _dbus_pending_call_set_timeout_error_unlocked在dbus源代码的副本中)
该 API 保证的一个例外是,如果您使用 DBUS_TIMEOUT_INFINITE 超时(在这种情况下:您要求它,您得到它)。在这种情况下,您将永远看不到回复:要么服务从不响应,但仍在总线上;要么或者,更病态的是,服务从不响应并离开总线,并且dbus-daemon 在尝试传递它合成的错误回复时内存不足,以报告永远不会有来自服务的回复。
【讨论】:
这取决于底层传输层,但除非你让它在 unix 域套接字或 TCP 以外的东西上工作(如果你要问,你不问),假设你会收到回复是安全的.
来源:
https://dbus.freedesktop.org/doc/dbus-tutorial.html#addresses
https://lists.freedesktop.org/archives/dbus/2007-June/008094.html
【讨论】: