我想知道直接通过低级C API调用dbus_connection_send_with_reply
使用D-Bus是否可以保证邮件传递?
更具体地说,它是否保证将单个消息实例传递到目标,或者如果失败则返回错误答复?
据我所知,接收应用程序可能不会对方法发出回复,在这种情况下,D-Bus会在超时后返回错误。但是,D-Bus协议是否涵盖所有其他潜在的故障?
答案 0 :(得分:3)
TL; DR:
永远无法保证交货。但是,即使邮件未送达,您也可以期待错误回复。
如果您使用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
在尝试传递它合成的错误答复时会耗尽内存,以便报告将永远不会有来自服务的回复
答案 1 :(得分:0)
这取决于底层的传输层,但除非你让它工作在unix域套接字或TCP之外的其他东西(如果你不得不问,你不会),可以安全地假设你会收到回复。
资料来源:
https://dbus.freedesktop.org/doc/dbus-tutorial.html#addresses
https://lists.freedesktop.org/archives/dbus/2007-June/008094.html