我们目前正在寻找RPC框架,不幸的是,我们无法找到任何具有信号功能的框架,但是我们需要它。我们查看了gRPC、Apache Thrift、Cap-n-Proto,发现它们中没有一个能像DBus那样提供现成的功能。值得一提的是,我们需要它作为IPC。另外,我们还需要监视另外一个套接字,以便一个用于RPC服务器,另一个用于另一个服务器。在DBus中,我们可以将它添加到glib的主循环中。我们的目标RPC必须允许这样做。
P.S. DBus并不是我们真正需要的,因为我们只需要客户机服务器架构,而不是客户机总线守护进程。
关于off-topic,我在这个问题上没有看到任何需要固执己见的答案。答案应包含事实,但不应包含意见。
发布于 2017-01-17 07:46:56
信号可以通过几种不同的方式实现在船长Proto之上。
对象链
一个Cap RPC调用需要很长时间才能完成,这是没有问题的。在同一连接上的其他调用可以正常地继续,并且一次可以有许多未完成的调用。因此,接收信号的一种策略是在返回之前有一个等待信号的呼叫。
许多RPC系统支持挂起调用,但还有一个额外的挑战:如果您有一个信号流,而且客户端观察流中的每个信号很重要,那么如果生成新信号的速度比客户机调用RPC读取信号的速度要快,那么事情就变得复杂起来。您需要为每个客户端保留一个缓冲区。但是,如果客户死了,停止了请求,怎么办?现在,您需要某种超时,然后清除它。
与大多数其他RPC系统不同,Cap支持动态生成新对象.因此,您可以将信号流表示为对象链。例如:
struct MyPayload { ... }
interface MyInterface {
subscribe @0 () -> (firstSignal :Signal(MyPayload));
# Subscribe to signals from this interface.
}
interface Signal(Type) {
# One signal in a stream of signals. Has a payload, and lets you
# wait for the next signal.
get @0 () -> (value :Type);
# Gets the payload value of this signal. (Returns immediately.)
waitForNext @1 () -> (nextSignal :Signal(Type));
# Waits for the next signal in the sequence, returning a new
# `Signal` object representing it.
}这大大简化了服务器端的状态管理,因为一旦所有客户端表明它们已经完成(通过销毁客户端引用,也就是“丢弃”引用),Cap将自动调用每个对象的析构函数。如果客户端断开连接,则隐式删除其所有引用。
回调
由于can允许RPC双向调用(客户端->服务器和服务器->客户端),所以可以使用回调实现“信号”或发布/订阅机制:
struct MyPayload { ... }
interface MyInterface {
subscribe @0 (cb :Callback(MyPayload)) -> (handle :Handle);
}
interface Callback(Type) {
call @0 (value :Type);
}
interface Handle {}客户端调用subscribe()并传递回调对象cb。然后,只要有信号,服务器就可以回电话给客户机。
注意,subscribe()返回一个Handle,它是一个没有方法的对象。其目的是检测客户端何时取消订阅。如果客户机删除handle,则会通知服务器(服务器端对象的析构函数将运行),然后服务器可以注销回调。这也处理了客户端断开连接的情况--所有对象引用都隐式地丢弃在断开连接上。
乍一看,这个解决方案看起来可能比对象链解决方案好得多,因为它很简单。但是,它有一个问题,就是现在有对象引用指向两个方向,这可能导致循环。在客户端代码中,您必须确保回调实现不“拥有”保持其注册的句柄,否则它将永远不会被清除(除非连接关闭)。您还必须确保在删除句柄之后仍然可以在短时间内调用回调,同时等待服务器注销回调。这些问题不存在于对象链解决方案中,这可能会使该解决方案更清晰地实现。
其他RPC系统
我在上面讨论了Cap,因为我是作者,而且它提供了比大多数RPC系统更多的选项。
如果您使用gRPC,您可以使用它的“流”功能来支持类似于信号的功能。流RPC可以随时间返回多个响应。
我不太确定。上一次我尝试的时候,请求必须是FIFO,这意味着长时间运行的RPCs是不可能的。然而,这是很久以前的事了,也许从那以后已经发生了变化。
https://stackoverflow.com/questions/41677473
复制相似问题