RpcClient类
public class RpcClient {
//配置
private RpcClientConfig config;
//序列化
private Encoder encoder;
private Decoder decoder;
//路由
private TransportSelector selector;
//无参构造 就使用默认的配置
public RpcClient() {
this(new RpcClientConfig());//调用有参构造 将默认值传过去
}
//有参构造 配置可以自己设定 -> 通过参数传过来
public RpcClient(RpcClientConfig config) {
this.config = config;
//属性初始化
this.encoder = ReflectionsUtils.newInstance(this.config.getEncoderClass());
this.decoder = ReflectionsUtils.newInstance(this.config.getDecoderClass());
this.selector = ReflectionsUtils.newInstance(this.config.getSelectorClass());
//selector初始化 1:server网络端点 2:连接个数 3:client网络模块
this.selector.init(
this.config.getServers(),
this.config.getConnectCount(),
this.config.getTransportClass()
);
}
//获取一个接口的代理对象 期望的是这个方法能够返回一个clazz的子类的对象 所以用个泛型
public <T> T getProxy(Class<T> clazz){
//基于JDK的动态代理
return (T) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class[]{clazz},
new RemoteInvoker(clazz,encoder,decoder,selector)
);
}
}
Proxy.newProxyInstance的使用及其作用可看JDK动态代理类
创建代理类
@Slf4j
//调用远程服务的代理类
public class RemoteInvoker implements InvocationHandler {
private Class clazz;
//序列化
private Encoder encoder;
private Decoder decoder;
//路由
private TransportSelector selector;
//参数 : 远程服务的class信息; 远程服务的序列化、反序列化 ; 选择一个远程网络连接;
public RemoteInvoker(Class clazz,Encoder encoder,Decoder decoder,TransportSelector selector) {
this.encoder = encoder;
this.decoder = decoder;
this.selector = selector;
this.clazz = clazz;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用远程服务:通过网络发生一个请求,等待server响应 返回数据 结束;
//创建请求对象
Request request = new Request();
request.setService(ServiceDescriptor.from(clazz,method));
request.setParameters(args);
//通过网络 调用远程服务 拿到response
Response response = invokeRemote(request);
if(response == null || response.getCode() != 0){
throw new IllegalStateException("fail to invoke remote: " + response );
}
//返回response信息 远程调用结束
return response.getData();
}
private Response invokeRemote(Request request) {
//拿到网络连接信息client
TransportClient client = null;
Response response = null;
try {
client = selector.select();//选择一个client路由
//序列化
byte[] bytes = encoder.encode(request);
//获取到的数据
InputStream revice = client.write(new ByteArrayInputStream(bytes));
byte[] inBytes = IOUtils.readFully(revice, revice.available());
//反序列化
response = decoder.decode(inBytes, Response.class);
}catch (IOException e){
log.warn(e.getMessage(),e);
response = new Response();
response.setCode(1);
response.setMessage("RpcClient got error: "+ e.getClass()+":" +e.getMessage());
}
finally {
if(client != null){
selector.release(client);
}
}
return response;
}
}