1.创建API模块
API主要定义对外开放的功能与服务接口
package com.xiepanpan.rpc.api;
/**
* @author: xiepanpan
* @Date: 2020/8/20 0020
* @Description:
*/
public interface IRpcHello {
String hello(String name);
}
package com.xiepanpan.rpc.api;
/**
* @author: xiepanpan
* @Date: 2020/8/20
* @Description: 计算接口
*/
public interface IRpcCalc {
/**
* 加
* @param a
* @param b
* @return
*/
public int add(int a,int b);
/**
* 减
* @param a
* @param b
* @return
*/
public int sub(int a,int b);
/**
* 乘
* @param a
* @param b
* @return
*/
public int mult(int a,int b);
/**
* 除
* @param a
* @param b
* @return
*/
public int div(int a,int b);
}
##2. 创建自定义协议
Netty中的HTTP处理要Netty内置的HTTP的编解码器来完成解析。现在我们来看自定义协议如何设定。在Netty中完成一个自定义协议其实非常简单,只需要定义一个普通的Java类即可。我们现在手写RPC主要是为了完成对Java代码的远程调用,类似于RMI(Remote Method Invocation,远程方法调用),大家应该都很熟悉了吧。在远程调用Java代码时,哪些内容是必须由网络来传输的呢?譬如,服务名称?需要调用该服务的哪个方法?方法的实参是什么?这些信息都需要通过客户端传送到服务端。
package com.xiepanpan.rpc.core.msg;
import java.io.Serializable;
/**
* @author: xiepanpan
* @Date: 2020/8/20
* @Description: 自定义传输协议的内容
*/
public class InvokerMsg implements Serializable {
/**
* 服务名称
*/
private String className;
/**
* 调用哪个方法
*/
private String methodName;
/**
* 参数列表
*/
private Class<?>[] params;
/**
* 参数值
*/
private Object[] values;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Class<?>[] getParams() {
return params;
}
public void setParams(Class<?>[] params) {
this.params = params;
}
public Object[] getValues() {
return values;
}
public void setValues(Object[] values) {
this.values = values;
}
}
3 实现Provider业务逻辑
package com.xiepanpan.rpc.provider;
import com.xiepanpan.rpc.api.IRpcHello;
/**
* @author: xiepanpan
* @Date: 2020/8/20 0020
* @Description:
*/
public class RpcHello implements IRpcHello {
public String hello(String name) {
return "hello,"+name+"!";
}
}
package com.xiepanpan.rpc.provider;
import com.xiepanpan.rpc.api.IRpcCalc;
/**
* @author: xiepanpan
* @Date: 2020/8/20
* @Description:
*/
public class RpcCalc implements IRpcCalc {
public int add(int a, int b) {
return a+b;
}
public int sub(int a, int b) {
return a-b;
}
public int mult(int a, int b) {
return a*b;
}
public int div(int a, int b) {
return a/b;
}
}
4 完成Registry服务注册
Registry(注册中心)的主要功能就是负责将所有Provider的服务名称和服务引用地址注册到一个容器中,并对外发布。Registry要启动一个对外的服务,很显然应该作为服务端,并提供一个对外可以访问的端口。先启动一个Netty服务,创建RpcRegistry类,具体代码如下。
package com.xiepanpan.rpc.register;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import