
com.zlyx.easynetty.client.core.AbstractNettyClient Maven / Gradle / Ivy
package com.zlyx.easynetty.client.core;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import com.alibaba.fastjson.JSONObject;
import com.zlyx.easycore.tool.EasyBuffer;
import com.zlyx.easycore.tool.Hex;
import com.zlyx.easycore.utils.ByteUtils;
import com.zlyx.easycore.utils.JsonUtils;
import com.zlyx.easycore.utils.LogUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;
/**
*
* @Auth 赵光
* @Desc 描述 Netty非塞式->长连接->客户端
* @Date 2019年4月8日
*/
public abstract class AbstractNettyClient extends AbstractBaseNettyClient implements Runnable {
protected String key;
protected ChannelFactory factory;
protected Class tClass;
public AbstractNettyClient(String key, String host, int port) throws Exception {
if(key == null) {
key = EasyBuffer.valueOf(this.hashCode());
}
this.key = key;
this.tClass = getTClass(this.getClass());
this.factory = new ChannelFactory(this, host, port);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
LogUtils.info(this.getClass(), key + "-> 客户端与服务端建立连接...");
this.write(doOnConnection(ctx));
}
/**
* 客户端与服务端建立连接时
*
* @param ctx
*/
public abstract T doOnConnection(ChannelHandlerContext ctx) throws Exception;
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
LogUtils.info(this.getClass(), key + "-> 客户端与服务端连接关闭...");
doCloseConnection(ctx);
}
/**
* 客户端与服务端断开连接时调用
*
* @param ctx
*/
public void doCloseConnection(ChannelHandlerContext ctx) throws Exception {
}
@SuppressWarnings("unchecked")
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
try {
byte[] response = (byte[]) message;
T data = null;
if (response != null) {
if (Hex.class == tClass) {
data = (T) Hex.newHex(ByteUtils.bytesToHexString(response));
} else if (byte[].class == tClass) {
data = (T) response;
} else if (JSONObject.class == tClass) {
data = (T) JsonUtils.parse(response);
} else {
data = (T) new String(response);
}
}
this.write(doService(ctx.channel(), data));
} catch (Exception e) {
LogUtils.err(e);
} finally {
ReferenceCountUtil.release(message);
}
}
/**
* 长连接交互业务
*
* @param
* @param channnel
* @param msg
* @return
* @throws Exception
*/
public abstract T doService(Channel channel, T res) throws Exception;
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
public void write(T msg) throws Exception {
if (msg != null) {
if (Hex.class == tClass) {
this.writeBytes(ByteUtils.hexStringToByte(((Hex) msg).getHex()));
} else if (byte[].class == tClass) {
this.writeBytes((byte[]) msg);
} else if (JSONObject.class == tClass) {
this.writeBytes(((JSONObject) msg).toString().getBytes());
} else if (String.class == tClass) {
this.writeBytes(((String) msg).getBytes());
} else if (Object.class == tClass) {
this.writeBytes(msg.toString().getBytes());
} else {
this.writeBytes(((String) msg).getBytes());
}
}
}
/**
* 向服务端输出Byte数组
*
* @param bytes byte数组
* @throws Exception
*/
public void writeBytes(byte[] bytes) throws Exception {
if (bytes != null) {
LogUtils.info(this.getClass(), key + " -> " + Arrays.toString(bytes));
factory.getChannel(key).writeAndFlush(bytes);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {
LogUtils.err(e);
ctx.close();
}
public String getKey() {
return key;
}
@Override
public void run() {
try {
this.factory.getChannel(key);
LogUtils.info(this.getClass(), key + "-> 建立一个连接");
} catch (Exception e) {
LogUtils.err(e);
}
}
/***
* 关闭通道
*/
public void close() {
this.factory.getChannel(key).close();
}
@SuppressWarnings("unchecked")
public Class getTClass(Class> tClass) throws Exception {
if (tClass.getGenericSuperclass().getTypeName().contains("<")) {
return (Class) ((ParameterizedType) tClass.getGenericSuperclass()).getActualTypeArguments()[0];
} else if (tClass != Object.class) {
return getTClass(tClass.getSuperclass());
}
throw new Exception("You must define an generics to specify data types!");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy