summercool-hsf &Netty3.X总结5--客户端异步调用service API

1.异步调用:

核心原理:利用JDK的动态代理类创建service代理对象,然后在InvocationHandler中调用channel发送数据, 同时在客户端维护一个回调对象callback集合或InvokeFuture对象集合,方便客户端接收消息的时候异步回调。

核心本质我的理解就是 futrue模式(本质就是setResult(),getResult()) + callback模式(本质就是个监听器对象)

相关核心代码:

创建代理:


/**
* @Title: wrapAsyncProxy4Service
* @Description: 为远程服务创建异步动态代理,返回代理对象
* @author 简道
* @param serviceInterface
* 远程服务接口
* @param asyncType
* 异步类型
* @param callback
* 回调
* @param dispatchStrategy
* 分发策略
* @return T 返回类型
*/
@SuppressWarnings("unchecked")
private static <T> T wrapAsyncProxy4Service(Class<T> serviceInterface, AsyncType asyncType,
AsyncCallback<?> callback, AsyncDispatchStrategy dispatchStrategy) {
if (serviceInterface == null) {
throw new IllegalArgumentException("serviceInterface can not be null.");
} else if (!serviceInterface.isInterface()) {
throw new IllegalArgumentException("serviceInterface is required to be interface.");
} else if (dispatchStrategy == null) {
throw new IllegalArgumentException("dispatchStrategy can not be null.");
}

InvocationHandler requestHandler = new AsyncServiceRequestHandler(serviceInterface.getSimpleName(), asyncType,
callback, dispatchStrategy);

// 创建代理
T serviceProxy = (T) Proxy.newProxyInstance(getClassLoader(serviceInterface), new Class[] { serviceInterface },
requestHandler);

return serviceProxy;
}


异步请求处理:


public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

RemoteServiceObject remoteServiceObject = new RemoteServiceObject();
remoteServiceObject.setMethodName(method.getName());
remoteServiceObject.setServiceName(serviceName);
remoteServiceObject.setArgs(args);

InvokeResult result;

if (AsyncType.Callback.equals(asyncType)) {
result = dispatchStrategy.dispatch(remoteServiceObject, callback);
} else {
result = dispatchStrategy.dispatch(remoteServiceObject, asyncType);
}

if (result != null && result.size() == 1) {
Object retObj = result.getFirstValue();

TLSUtil.setData(InvokeFuture.class, retObj);
} else if (AsyncType.Future.equals(asyncType)) {
MultiInvokeFuture multiInvokeFuture = new MultiInvokeFuture();
Set<Object> keySet = result.keySet();

for (Object groupName : keySet) {
multiInvokeFuture.addFuture((InvokeFuture) result.get(groupName));
}

TLSUtil.setData(InvokeFuture.class, multiInvokeFuture);
}

return ReflectionUtil.getDefaultValue(method.getReturnType());
}



消息分发:


@Override
public InvokeResult dispatch(Object message, AsyncType asyncType) {
if (message == null) {
throw new IllegalArgumentException("Message can not be null.");
} else if (!service.isAlived()) {
throw new IllegalStateException("service is not alived.");
} else if (AsyncType.Callback.equals(asyncType)) {
throw new IllegalArgumentException("only support AsyncType.None and AsyncType.Future.");
}

// 默认为None
if (asyncType == null) {
asyncType = AsyncType.Default;
}

InvokeResult invokeResult = new InvokeResult();
HsfChannel channel = getChannel(service.getGroups());

switch (asyncType) {
case Default:
invokeResult.put(((HsfChannel) channel).getChannelGroup().getName(), channel.write(message));
break;

case Future:
invokeResult.put(channel.getChannelGroup().getName(), channel.writeAsync(message));
break;
}

return invokeResult;
}


HsfChannel write并保存维护callback对象:


public void writeAsync(Object msg, final AsyncCallback<?> callback) {
// 创建Request对象
RequestObject request = new RequestObject();
final long seq = getSeq();
request.setSeq(seq);
request.setTarget(msg);

//
if (callback != null) {
// 流量控制
flowAcquire();
try {

// 存储callback
callbacks.put(seq, callback);

//
Object param = getCallbackMessage(msg);
if (param != null && LangUtil.parseBoolean(service.getOption(HsfOptions.HOLD_CALLBACK_PARAM), false)) {
// 存储参数,缓存Callback方式发送的消息,缓存后将会在发送失败时回调doException方法参数传入, default is false
cbParamMap.put(seq, param);
}

// 发送Request对象
ChannelFuture channelFuture = write(request);
channelFuture.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {//异常处理
callbacks.remove(seq);
//
Object m = cbParamMap.remove(seq);
try {
CallbackRegister.setCallbackParam(m);
//
callback.doExceptionCaught(future.getCause(), HsfChannel.this, m);
} catch (Exception e) {
logger.error(StackTraceUtil.getStackTrace(e));
} finally {
CallbackRegister.clearCallbackParam();
}
}
}
});
} catch (Throwable e) {
// 释放流量
flowRelease();
}
} else {
// no callback
request.setNeedCallback(false);
//
write(msg);
}
}


读取响应消息并回调:


@SuppressWarnings({ "rawtypes", "unchecked" })
private void processResponse(ChannelHandlerContext ctx, ResponseObject response, HsfChannel channel) {
// 处理Seq为-1的异常信息
if (response.getSeq() == -1) {
if (response.getCause() != null) {
ctx.sendUpstream(new DefaultExceptionEvent(channel, response.getCause()));
}
return;
}

// Future方式
InvokeFuture future = channel.getFutures().remove(response.getSeq());
if (future != null) {
if (response.getCause() != null) {
future.setCause(response.getCause());
} else {
future.setResult(response.getTarget());
}
// 释放流量
flowRelease(channel);
}

// Callback方式
AsyncCallback callback = channel.getCallbacks().remove(response.getSeq());
if (callback != null) {
//
Object param = channel.getCallbackParamMap().remove(response.getSeq());
try {
CallbackRegister.setCallbackParam(param);
//
if (response.getCause() != null) {
callback.doExceptionCaught(response.getCause(), channel, null);
} else {
callback.doCallback(response.getTarget());
}
} catch (Throwable ex) {
logger.error(StackTraceUtil.getStackTrace(ex));
} finally {
// 释放流量
flowRelease(channel);
//
CallbackRegister.clearCallbackParam();
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值