com.github.houbb.config.socket.client.thread.ConfigClientThreadBak Maven / Gradle / Ivy
/*
* Copyright (c) 2019. houbinbin Inc.
* rpc All rights reserved.
*/
package com.github.houbb.config.socket.client.thread;
import com.alibaba.fastjson.JSON;
import com.github.houbb.config.socket.client.handler.ConfigClientHandler;
import com.github.houbb.config.socket.client.rpc.dto.RpcAddress;
import com.github.houbb.config.socket.client.rpc.dto.RpcChannelFuture;
import com.github.houbb.config.socket.client.rpc.handler.ChannelHandlerFactory;
import com.github.houbb.config.socket.client.rpc.handler.ChannelHandlers;
import com.github.houbb.config.socket.client.support.invoke.InvokeService;
import com.github.houbb.config.socket.common.exception.ConfigTimeoutException;
import com.github.houbb.config.socket.common.exception.RespCode;
import com.github.houbb.config.socket.common.req.CommonReq;
import com.github.houbb.config.socket.common.resp.CommonResp;
import com.github.houbb.config.socket.common.rpc.RpcMessageDto;
import com.github.houbb.config.socket.common.util.BeanUtils;
import com.github.houbb.heaven.util.common.ArgUtil;
import com.github.houbb.heaven.util.id.impl.Ids;
import com.github.houbb.heaven.util.util.CollectionUtil;
import com.github.houbb.log.integration.core.Log;
import com.github.houbb.log.integration.core.LogFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
* rpc 客户端
*
* Created: 2019/10/16 11:21 下午
* Project: rpc
*
* @author houbinbin
* @since 0.0.2
*/
public class ConfigClientThreadBak {
private static final Log log = LogFactory.getLog(ConfigClientThreadBak.class);
/**
* 服务端地址
*/
private List serverAddressList;
/**
* 客户端处理 handler
*
* @since 0.0.4
*/
private ConfigClientHandler channelHandler;
/**
* 调用服务管理
*
* @since 1.0.0
*/
private InvokeService invokeService;
/**
* 是否检核服务端的可用性
*
* @since 1.1.0
*/
private boolean check;
/**
* 超时时间
* 单位:毫秒
*/
private long timeoutMills;
/**
* channel 列表
*
* @since 1.1.0
*/
private List channelFutureList;
public ConfigClientThreadBak serverAddressList(List serverAddressList) {
this.serverAddressList = serverAddressList;
return this;
}
public ConfigClientThreadBak invokeService(InvokeService invokeService) {
this.invokeService = invokeService;
return this;
}
public ConfigClientThreadBak check(boolean check) {
this.check = check;
return this;
}
public ConfigClientThreadBak timeoutMills(long timeoutMills) {
this.timeoutMills = timeoutMills;
return this;
}
/**
* 初始化
*/
public void start() {
ArgUtil.notEmpty(serverAddressList, "serverAddressList");
ArgUtil.notNull(invokeService, "invokeService");
this.channelFutureList = initChannelFutureList(this.serverAddressList);
this.channelHandler = new ConfigClientHandler(invokeService, null);
}
/**
* 获取 channel future
* @return channel future
*/
private ChannelFuture getChannelFuture() {
int index = ThreadLocalRandom.current().nextInt(channelFutureList.size());
return channelFutureList.get(index).channelFuture();
}
/**
* 初始化列表
*
* @param rpcAddressList 地址
* @return 结果
* @since 0.1.6
*/
private List initChannelFutureList(List rpcAddressList) {
// 检测可用性
if (check) {
//1. 列表为空
if (CollectionUtil.isEmpty(rpcAddressList)) {
log.error("[Rpc Client] rpc address list is empty!");
throw new RuntimeException();
}
//2. 初始化
return ChannelHandlers.channelFutureList(rpcAddressList, new ChannelHandlerFactory() {
@Override
public ChannelHandler handler() {
return ChannelHandlers.logHandler(channelHandler);
}
});
}
// 如果不检测可用性
List resultList = new ArrayList<>();
if (CollectionUtil.isEmpty(rpcAddressList)) {
log.warn("[Rpc Client] rpc address list is empty, without check init.");
return resultList;
}
// 如果异常,则捕获
for (RpcAddress rpcAddress : rpcAddressList) {
try {
RpcChannelFuture future = ChannelHandlers.channelFuture(rpcAddress, new ChannelHandlerFactory() {
@Override
public ChannelHandler handler() {
return ChannelHandlers.logHandler(channelHandler);
}
});
resultList.add(future);
} catch (Exception exception) {
log.error("[Rpc Client] rpc address init failed, without check init. {}", rpcAddress, exception);
}
}
return resultList;
}
public R callServer(T commonReq, Class respClass) {
final String traceId = Ids.uuid32();
commonReq.setTraceId(traceId);
commonReq.setRequestTime(System.currentTimeMillis());
RpcMessageDto rpcMessageDto = new RpcMessageDto();
BeanUtils.copyProperties(commonReq, rpcMessageDto);
rpcMessageDto.setJson(JSON.toJSONString(commonReq));
// 请求类
rpcMessageDto.setRequest(true);
// 关闭当前线程,以获取对应的信息
// 使用序列化的方式
final byte[] bytes = JSON.toJSONBytes(rpcMessageDto);
ByteBuf byteBuf = Unpooled.copiedBuffer(bytes);
// 添加调用服务
invokeService.addRequest(traceId, timeoutMills);
// 遍历 channel
Channel channel = getChannelFuture().channel();
channel.writeAndFlush(byteBuf);
log.info("client 注册 {}", JSON.toJSON(commonReq));
channel.closeFuture().syncUninterruptibly();
//channelHandler 中获取对应的响应
RpcMessageDto messageDto = invokeService.getResponse(traceId);
if (RespCode.TIMEOUT.getCode().equals(messageDto.getRespCode())) {
throw new ConfigTimeoutException();
}
String respJson = messageDto.getJson();
return JSON.parseObject(respJson, respClass);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy