手把手实现RPC框架--简易版Dubbo构造(二)从一个简单实现开始

本节commit源码地址:ca82236
盗一张Guide哥的图哈
手把手实现RPC框架--简易版Dubbo构造(二)从一个简单实现开始_第1张图片

我们首先要思考,RPC框架的原理:原理其实很简单,客户端和服务端都可以访问到通用的接口,但是只有服务端有这个接口的实现类,客户端调用这个接口的方式,是通过网络传输,告诉服务端我要调用这个接口,服务端收到之后找到这个接口的实现类,并且执行,将执行的结果返回给客户端,客户端拿到返回的结果,结束。
我们先进行最基本的实现,然后一步一步完善,假设我们现在知道服务端的地址,尝试来实现一下这个过程。

API通用接口

定义接口

public interface HelloService {
    String hello(HelloObject object);
}

hello方法需要传递一个对象,HelloObject对象,注意这个对象需要实现Serializable接口,因为它需要在调用过程中从客户端传递给服务端,必须进行序列化。
 

//自动加上所有属性的get set toString hashCode equals方法
@Data
//添加一个含有所有已声明字段属性参数的构造函数
@AllArgsConstructor
public class HelloObject implements Serializable {
    //Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。
    //实现了Serializable接口的类可以被ObjectOutputStream转换为字节流。
    //同时也可以通过ObjectInputStream再将其解析为对象。
    //序列化是指把对象转换为字节序列的过程;反序列化则是把持久化的字节文件数据恢复为对象的过程。

    private Integer id;
    private String message;

}

接着我们在服务端对这个接口进行实现,实现的方式也很简单,返回一个字符串就行。

public class HelloServiceImpl implements HelloService {

    /**
     * 使用HelloServiceImpl初始化日志对象,方便在日志输出的时候,可以打印出日志信息所属的类。
     */
    private static final Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class);

    @Override
    public String hello(HelloObject object) {
        //使用{}可以直接将getMessage()内容输出
        logger.info("接收到:{}", object.getMessage());
        return "这是调用的返回值:id=" + object.getId();
    }
}

传输协议

就是在客户端和服务端之间的传输的数据规定一个固定格式,具体采用什么格式,可以考虑服务端需要哪些信息,才能唯一确定服务端需要调用哪个接口的哪个方法呢?

首先,肯定要知道接口的名字和方法的名字,但是由于方法重载的缘故,我们还需要这个方法的所有参数的类型,最后,服务端处理时,还需要参数的实际值,那么服务端知道以上四个条件,就可以找到这个方法并且调用处理了。我们把这四个条件写到一个对象里,到时候传输时传输这个对象就行了。即RpcRequest对象

@Data
//使用创建者模式,一次性给所有变量初始赋值
@Builder
public class RpcRequest implements Serializable {
    /**
     * 待调用接口名称
     */
    private String interfaceName;
    /**
     * 待调用方法名称
     */
    private String methodName;
    /**
     * 待调用方法的参数
     */
    private Object[] parameters;
    /**
     * 待调用方法的参数类型
     */
    private Class[] paramTypes;
}

服务器调用完这个方法后,需要给客户端返回哪些信息呢?如果调用成功的话,显然需要返回值,如果调用失败了,就需要失败的信息,这里封装一个RpcResponse对象作为返回

@Data
public class RpcResponse implements Serializable {
    /**
     *响应状态码
     */
    private Integer statusCode;
    /**
     *响应状态码对应的信息
     */
    private String message;
    /**
     *成功时的响应数据
     */
    private T data;

    /**
     * @description 成功时服务端返回的对象
     * @param [data]
     * @return [com.panda.rpc.entity.RpcResponse]
     * @date [2021-02-03 17:31]
     */
    public static  RpcResponse success(T data){
        RpcResponse response = new RpcResponse<>();
        response.setStatusCode(ResponseCode.SUCCESS.getCode());
        response.setData(data);
        return response;
    }

    /**
     * @description 失败时服务端返回的对象
     * @param [code]
     * @return [com.panda.rpc.entity.RpcResponse]
     * @date [2021-02-03 17:42]
     */
    public static  RpcResponse fail(ResponseCode code){
        RpcResponse response = new RpcResponse<>();
        response.setStatusCode(code.getCode());
        response.setMessage(code.getMessage());
        return response;
    }
}

响应状态码ResponseCode对象定义

@AllArgsConstructor
@Getter
public enum ResponseCode {

    SUCCESS(200,"调用方法成功"),
    FAIL(500,"调用方法失败"),
    NOT_FOUND_METHOD(501,"未找到指定方法"),
    NOT_FOUND_CLASS(502,"未找到指定类");

    private final int code;
    private final String message;
}

本节结束……

你可能感兴趣的:(JAVA,rpc,dubbo)