Server
• RpcServer:rpc功能模块与⽹络通信部分结合RpcServer分为两部分 1.提供函数调用服务的服务端 2.提供服务注册的客户端
对内提供好rpc服务的路由关系管理map<method,服务描述对象>,以及rpc请求消息的分发处理函数。给Dispatcher提供onRpcRequest rpc请求的回调函数,根据请求中的method(),从map中找到对应的服务描述对象 进行参数检查,无误调用函数处理 最后向服务端返回应答。
右侧serviceRegister(method, service) 是服务端本地注册接口,用于将某个 method(方法名)与其对应的 service(服务描述对象)进行绑定,注册到本地的 RpcRouter 中,便于后续接收到 RPC 请求时进行路由调用对应的函数服务。
但仅仅本地知道能提供哪些服务还不够,如果希望其他客户端也能发现这些服务并远程调用,就必须通过 RegistryClient注册客户端 将服务信息(method 与 host 地址)注册到服务注册中心 RegistryServer。
• RegistryServer:服务发现注册功能模块与⽹络通信部分结合
对内提供好服务提供者和服务发现者的数据管理 。给Dispatcher提供服务操作请求的分发处理函数onServiceRequest,分为服务发现/服务注册。
服务发现:返回能提供该method函数的主机地址列表
服务注册:将提供者信息管理起来
PDManager分为服务提供者管理,服务发现者管理。1.进行服务注册 提供者管理要add新增提供者 发现者管理要给订阅该method方法的发现者进行服务上线通知ontifyOffline。2.进行服务发现 发现者管理add新增发现者 并返回method方法提供者列表(提供者管理)应答。
onShutdown服务提供者或者发现者断开连接时的回调函数,1.提供者断开连接 发现者管理发送服务下线通知ontifyOffline 提供者管理del删除该提供者的管理 2.发现者断开 不需要通知 发现者管理del删除该发现者的管理
• TopicServer:发布订阅功能模块与⽹络通信部分结合对内完成主题map<key,topic>和订阅者信息map<conn,subscriber>的管理。topic包含主题名称+当前主题的订阅者列表vector<sub>,sub包含订阅者conn+订阅的主题列表名称vector<string>.
给Dispatcher回调函数onTopicRequest处理主题操作的请求,1.主题创建2.主题删除3.订阅主题4.取消订阅5.向主题发布消息
双向映射管理:一方面维护“主题 → 订阅者”,另一方面维护“订阅者 → 主题”
1.订阅主题 订阅者sub中新增主题 被订阅的主题topic对象中订阅者列表也要新增订阅者
2.取消订阅 同理订阅者删除了主题 主题对象中也要删除订阅者
3.删除主题 map<key,topic>删除映射,订阅该主题的订阅者中也要删除该主题
4.连接断开的回调函数onShutdown 处理订阅者断开连接, map<conn,sub>删除映射 订阅者订阅的所以主题中删除该订阅者
服务端总体逻辑
服务端总体有3个回调函数注册到Dispatcher中,onRpcRequest 处理rpc请求的 onServiceRequest处理服务请求 onTopicRequest处理主题操作请求的
Client
将以上模块进⾏整合就可以实现各个功能的客⼾端了。
• RegistryClient:服务注册功能模块与⽹络通信客⼾端结合
服务注册客户端 提供一个服务注册的接口registryMethod 通过requestor进行发送服务注册请求并等待应答。给Dis注册的回调函数onResponse是Requestor模块的接收应答的回调函数,毕竟请求由Requestor发送 也由它设置回调函数接收并处理。
• DiscoveryClient:服务发现功能模块与⽹络通信客⼾端结合
服务发现客户端 对内提供处理服务端主动推送的服务上线/下线通知请求的分发接口,对外提供服务发现接口,设置服务下线的处理回调(当作成员函数 构造时传入 删除连接池中的该服务的长连接)
所以给Dispatcher的回调函数有两个,1onResponse客户端主动发送服务发现请求的应答回调 2.onServiceRequest处理服务端主动推送的服务上线/下线通知请求的回调(服务下线时调用_offline_callback删除长连接)。
• RpcClient:DiscoveryClient & RPC功能模块与⽹络通信客⼾端结合这个RpcClient也是分为两部分 1.提供rpc调用的客户端 2.提供服务发现的服务发现客户端
对外提供3个call函数,1.同步2.异步future3.异步回调,但内部是套用Requestor的3个send函数进行调用的。其中同步call是调用的同步send(内部套用异步send+外部等待) 23异步future和异步回调call都是调用的回调send,2异步future是在回调函数中设置的set_value(bind捕获为了延长promise的生命周期)
call进行rpc调用前我们必须要找到能提供服务的服务端地址,怎么知道?向注册中心进行服务发现,这就需要服务端发现客户端 进行服务发现。向外提供1.服务发现接口2.服务上线/下线的回调函数
• TopicClient:发布订阅功能模块与⽹络通信客⼾端结合发布订阅客户端,对内提供主题消息推送的消息分发处理回调函数onpublish(根据本地map<key,cb>调用对应主题的回调函数 订阅主题时候传入的),对外提供主题操作的函数1.主题创建2.主题删除3.订阅主题4.取消订阅5.主题消息发布
这里给Dispathcer传入的回调函数也是两个,1.onResponse客户端主动发送服务发现请求的应答回调 2.onPublish 服务端主动发送的主题消息 进行分发调用对应的回调函数。
客户端总体逻辑图
dispatcher中存入有三个回调函数,1.客户端主动requestor()发送请求,自然由它的回调函数onResponse进行处理 2.服务端主动发送的消息 主题消息的发布,对订阅该主题的客户端发送消息,对于被动接收到的主题消息 topic客户端自己设置回调函数onPublish给dispatcher模块。3.服务端主动发送的消息 服务上线/下线通知 registry客户端设置回调函数onServiceRequest给disoatcher模块
服务端抽象层
主 Reactor 负责监听 listenfd 上的新连接请求,一旦有连接到来就通过 accept() 建立连接,获取客户端的套接字 connfd。(并封装为 BaseConnection 对象)
从 Reactor 则负责监听所有客户端套接字的 IO 事件(如可读)。当客户端发来数据,服务端就通过对应的 connfd 从内核读取数据,先写入 BaseBuffer 输入缓冲区。
然后上层 Protocol 模块从缓冲区中读取数据,处理粘包拆包,将原始字节数据反序列化为 BaseMessage 对象,最终由 Dispatcher 根据 msg->type() 派发到注册的业务处理回调函数中去。
客户端连接建立时 会调用服务端外部提供的2个set接口,onClose onConn,而onMessage回调是Dispatcher设置的 onMessage把messgae传给Dis让它按消息类型派发数据
(Dispatcher 里的回调函数是由各个业务模块在初始化阶段,通过 registerHandler(msgType, 回调函数) 主动注册进去的)
客户端抽象层
客户端的 Reactor 维护了一条与服务端的连接,监听这个套接字 获取服务端返回的应答和主题服务上下线推送/主题消息发布广播,并通过 Dispatcher 根据消息类型调用对应的回调函数。
给外部提供了5个接口,1.connect()建立客户端到服务端的 TCP 连接 2.shutdown()主动关闭当前连接 3.setCloseCallback()关闭连接回调函数 4.setConnectionCallback()连接建立成功回调函数 5.send()发送请求
oMessage也是由dis提供 对应类型的回调函数由各模块初始化时传入
具象层
针对不同的请求,从BaseMessage中派⽣出不同的请求和响应类型,以便于在针对指定消息处理时,能够更加轻松的获取或设置请求及响应中的各项数据元素。
BaseMessage最基础的消息结构体:消息id 消息类型mtype(epc topic service)
JsonMessage继承BaseMessage:新增body字段 存储请求/响应的内容
JsonMessage子类可以分为 请求和响应,因为如果是响应类的话 需要有响应码 check()检查响应是否正确。
1.JsonRequest 请求消息的基类 无新增字段
1.RpcRequset 新增 1.method调用的函数名 2.parameters 参数(json格式 参数名:类型)
2.TopicRequset 1.key主题名 2.optype主题操作类型(创建/删除/订阅/取消订阅/主题发布) 3.(msg)如果是主题发布 就有这个字段 主题发布的内容
3.ServiceRequset 1.method函数名 2.optype服务操作类型(注册/发现/上线/下线)
3.host 告诉服务端自己的地址 (仅在注册、上线时需要)
2.JsonResponse 应答消息的基类 重写chekc() 如子类需要根据自己结构判断可再进行重写
1.RpcResponse 1.rcode返回码 2.result 结果数据
2.TopicResponse 1.rcode返回码 主题的操作应答只需要返回是否完成就可以
3.ServiceResponse
注册/上线/下线操作:1.rcode返回码 2.optype服务操作类型
发现操作:1.rcode 2.optype 3.method要发现的函数 4.hosts能提供method方法的主机地址列表
业务层
业务层就是基于底层的通信框架,针对项⽬中具体的业务功能的实现了,⽐如Rpc请求的处理,发布订阅请求的处理以及服务注册与发现的处理等等。
1.rpc请求处理
1.Client模块:对外提供call()接口,给用户进行rpc调用。内部通过Requestor发送rpc请求。
Requestor提供onResponse给Dispatcher模块 处理Requestor发送请求返回的应答。
2.中间传输层模块:通过底层网络通信NetWork发送数据,Dispatcher模块根据消息类型的不同调用对应的回调函数处理。
3.Server模块:对内完成method->函数的映射管理,并提供onRpcRequest给Dispatcher模块 处理rpc请求消息的回调函数,调用对应的rpc函数 并返回应答。
2.发布订阅请求的处理
1.Client模块:PSManager对外提供5个接口,这些请求都是通过Requestor()进行发送,因此Requestor要给Dis提供onResponse回调处理 这些请求对应的响应。除此之外,PSManager还要给Dis提供onPublish函数,处理主题消息,因为这是服务端主动发送的 并不是Requestor发送请求返回的响应,所以单独处理。
2.Network 负责客户端与服务端之间的底层连接及消息收发 Dispatcher消息派发
3.Server模块:PSManger给Dis提供onTopicRequest 处理topic主题消息调用对应函数完成主题创建/删除/... 并发送操作是否完成的应答。 如果是主题发布,服务端还需要主动给订阅该主题的客户端进行广播,通过Publish函数send发送消息。
3.服务注册&发现
1.Client模块:PDManager模块分为两部份 1.Provider服务提供者 对外提供服务注册serviceRegistry() 通过Requestor发送服务注册请求。2.Discoverer服务发现者 对外提供服务发现serviceDiscovery() 也是通过Requestor发送服务发现请求。除此之外,还要给Dis提供onServiceRequest来处理服务端主动发送的 服务上线/下线消息的回调处理函数。
2.
3.Server模块:PDManager给Dis提供一个统一的接口onServiceRequest来处理客户端发来的服务注册/服务发现请求,1.服务注册 Pro新增提供者 Discover进行服务上线通知 返回注册成功应答 2.服务发现 Discover新增发现者 返回发现成功应答包含服务提供者地址
因此服务发现者 需要有服务上线/下线通知的函数 onlineNotify/offlineNotify,服务端给客户端主动发送消息。
整体设计框架
整个项目的实现分为三层,抽象层 具象层 业务层。
抽象层 将底层的网络通信机制(BaseServer BaseClient Basebuffer BaseConnection都是封装的Muduo库) 应用层通信协议(自己实现的LVProtocol) 请求响应的数据结构进行统一的封装抽象(BaseMessgae 派生出对应的子类),还有个回调函数MessageCallback 将原始字节流转化为message对象时触发 给Dispatcher进行派发。
具象层 底层网络通信借助Muduo库 通信协议自己实现的LV通信协议 请求响应的数据结构根据三个模块派生对应的子类
业务层 三个模块各自提供处理对应请求的回调函数给Dispatcher模块。
Dispatcher模块MType对应的回调函数
请求类都是由对应的服务端提供回调函数1.rpc服务端 onRpcRequest 2.服务注册/发现服务端onServiceRequest 3.主题服务端onTopicRequest
响应类由Requestor提供的onResponse处理
主题消息发布topic客户端提供的publish 服务上下线通知服务客户端的onServiceRequest
功能场景 | 消息类型(MType) | 说明 |
---|---|---|
RPC 请求 | MType::REQ_RPC | 客户端发起 RPC 函数调用请求 |
RPC 响应 | MType::RSP_RPC | 服务端返回 RPC 执行结果 |
Topic 请求 | MType::REQ_TOPIC | 客户端执行主题相关操作(订阅、发布等) |
Topic 响应 | MType::RSP_TOPIC | 服务端返回主题请求处理结果 |
服务请求 | MType::REQ_SERVICE | 客户端请求服务注册/发现/上下线等操作 |
服务响应 | MType::RSP_SERVICE | 服务端对服务请求的响应 |