HandyIpc icon indicating copy to clipboard operation
HandyIpc copied to clipboard

合同接口(IpcContract)支持事件

Open DingpingZhang opened this issue 2 years ago • 1 comments

背景:

当前的合同接口仅支持方法成员,按目前设定:Server 在同一个域内应该是唯一的,不允许启动第二个 Server 实例,以避免 Client 无法区分服务的提供者;而 Client 方则允许创建多个实例与唯一的 Server 交互,但交互方式仅为:Client 调用 Server,Server 在本次调用中应答一次 Client,是单对单的交互方式,还缺乏一种单对多的通知方式,即多播事件。

方案:

使当前的合同接口可以定义事件,事件的行为应当是:Server 发布事件后,所有 Client 实例(可能有多个)中订阅了该事件的 Handler 都应该被触发。Client 之间若想交互,仅可以通过调用 Server 方法以触发某个 Server Event 的方式进行。

实现:

该 Feature 本质上是:

  1. Server 和 Client 的角色互换,
  2. 且 Server 还需要储存多个连接到它的 Client 实例,以做到多播。

考虑到以下问题,我们并不能简单地将目前的 SenderBaseReceiverBase 进行互换:Tcp 中,同一台机器中的同一个端口仅允许被一个实例监听,如果 Client 侧也创建 ReceiverBase,那么端口号将不方便选取,选取后也还需要通知 Server 侧,实现起来比较麻烦;NamedPipe 虽然允许创建多个同名 Pipe,但多个进程中包含的同名 ServerStream 也会导致 Client 无法区分正确的连接目标。 所以,应当借助 Tcp 和 NamedPipe 的全双工能力实现反向的通知。具体的:

  1. 当 Client 第一次订阅事件时(可以在 ClientProxy 中拦截到),Client 向 Server 发送一个订阅请求;
  2. Server 处理该请求,并缓存本次连接。当 Server 中该事件被触发后,将向所有缓存中的连接推送消息;
  3. 当 Client 取消事件订阅后,并且 handlerCounter 计数器归零时,Client 向 Server 发送一个订阅请求;
  4. Server 释放相应的连接资源。

DingpingZhang avatar Aug 10 '21 02:08 DingpingZhang