看了这篇你就会手写RPC框架了 (3)

服务代理类由客户端代理工厂类产生,代理方式是基于Java的动态代理。在处理类ClientInvocationHandler的invoke函数中,定义了一系列的操作,包括获取服务、选择服务提供者、构造请求对象、编组请求对象、网络请求客户端发送请求、解组响应消息、异常处理等。

3.3.2.4 消息协议 /** * 消息协议,定义编组请求、解组请求、编组响应、解组响应规范 * * @author 东方雨倾 * @since 1.0.0 */ public interface MessageProtocol { /** * 编组请求 * * @param req 请求信息 * @return 请求字节数组 * @throws Exception 编组请求异常 */ byte[] marshallingRequest(LeisureRequest req) throws Exception; /** * 解组请求 * * @param data 请求字节数组 * @return 请求信息 * @throws Exception 解组请求异常 */ LeisureRequest unmarshallingRequest(byte[] data) throws Exception; /** * 编组响应 * * @param rsp 响应信息 * @return 响应字节数组 * @throws Exception 编组响应异常 */ byte[] marshallingResponse(LeisureResponse rsp) throws Exception; /** * 解组响应 * * @param data 响应字节数组 * @return 响应信息 * @throws Exception 解组响应异常 */ LeisureResponse unmarshallingResponse(byte[] data) throws Exception; } /** * Java序列化消息协议 * * @author 东方雨倾 * @since 1.0.0 */ public class JavaSerializeMessageProtocol implements MessageProtocol { private byte[] serialize(Object obj) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(obj); return bout.toByteArray(); } @Override public byte[] marshallingRequest(LeisureRequest req) throws Exception { return this.serialize(req); } @Override public LeisureRequest unmarshallingRequest(byte[] data) throws Exception { ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)); return (LeisureRequest) in.readObject(); } @Override public byte[] marshallingResponse(LeisureResponse rsp) throws Exception { return this.serialize(rsp); } @Override public LeisureResponse unmarshallingResponse(byte[] data) throws Exception { ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)); return (LeisureResponse) in.readObject(); } }

消息协议主要是定义了客户端如何编组请求解组响应,服务端如何解组请求编组响应这四个操作规范。本文提供了Java序列化与反序列化的实现,感兴趣的读者可以基于其他序列化技术实现其他消息协议(偷偷说一句:Java的序列化性能很不理想)。

3.4 服务端编写 3.4.1 服务端需要做什么?

首先,服务端要提供远程服务,必须具备服务注册及暴露的能力;在这之后,还需要开启网络服务,供客户端连接。有些项目可能既是服务提供者,又是服务消费者,那什么时候开启服务,什么时候注入服务呢?这里我们引入一个RPC处理者的概念,由它来帮我们开启服务,以及注入服务。

3.4.3 具体实现

先看看服务端的代码结构:

image-20200722234608540

服务端做的事情也很简单,注册服务并暴露服务,然后开启网络服务;如果服务端也是消费者,则注入远程服务。

服务注册和服务注入依赖两个自定义注解来实现:

@Service:注册服务

@InjectService:注入服务

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpygwy.html