一个由Java编写的RPC项目,使用简单,支持同步以及异步调用。
程序使用Netty作为通讯基础组件,支持可替换序列化组件(暂时支持Kryo)。
本程序在 JDK8(Oracle JDK 8 build 1.8.0_231-b11) 平台编写和测试,使用默认Gradle Wrapper构建。
./gradlew simplerpc:clean simplerpc:jar
|-com
|-jelipo
|-test
> Main.java
> People.java
> ProxyInterface.java
> ProxyInterfaceImpl.java
public class People {
private String name;
private int age;
//如果RPC要传输一个对象,这么此对象必须要有个空构造方法。
public People() {}
public People(String name, int age) {
this.name = name;
this.age = age;
}
...getter and setter...
}
@Rpc //在RPC接口上添加@Rpc注解
public interface ProxyInterface {
String getUserData(People people);
CompletableFuture<People> getUserDataAsysn(String info);
}
@RpcImpl //在实现类上添加@RpcImpl注解
public class ProxyInterfaceImpl implements ProxyInterface {
@Override
public String getUserData(People people) {
return "Sync: Name:" + people.getName() + ". Age:" + people.getAge();
}
@Override
public CompletableFuture<People> getUserDataAsysn(String info) {
return CompletableFuture.supplyAsync(() -> {
String[] split = info.split(",");
return new People(split[0], Integer.parseInt(split[1]));
});
}
}
//设置端口
int port = 18080;
//启动RPC服务器
RpcServer rpcServer = new RpcServer()
.port(port)
//扫描被注解的类的路径
.classesPath("com.jelipo.test")
.start();
//启动RPC客户端
RpcClient rpcClient = new RpcClient()
//连接RPC服务
.hostAndPort("localhost", port)
.classesPath("com.jelipo.test")
.connect();
//从client中获取RPC接口的代理类。
ProxyInterface proxyInterfaceImpl = rpcClient.getRpcImpl(ProxyInterface.class);
People people = new People("小丽", 18);
//支持的参数和返回类型包括Java的基本类型、String、只包含基本类型(可嵌套)且有空构造方法的POJO类.
String result = proxyInterfaceImpl.getUserData(people);
System.out.println(result);
ProxyInterface proxyInterfaceImpl = rpcClient.getRpcImpl(ProxyInterface.class);
CompletableFuture<People> completableFutureResult = proxyInterfaceImpl.getUserDataAsysn("老王,35");
completableFutureResult.whenComplete((people1, throwable) -> {
System.out.println("Async: Name " + people1.getName() + " Age " + people1.getAge());
});
//当异步调用远程方法,远程方法抛出异常时的处理。
CompletableFuture<People> exceptionResult = proxyInterfaceImpl.getUserDataAsysn("不知道老王几岁");
exceptionResult.whenComplete((people2, throwable) -> {
System.out.println(people2);
}).exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
- 注册中心支持(暂时未定)
- 更多的序列化支持(初步计划JSON和Hessian)
- 更多的网络协议支持(为了网络兼容性使用HTTP)
- 支持方法级别的Config注解配置(如超时设置、指定Server等)
- 对于Netty的长连接使用多个连接保证稳定性