com.iteaj.iot.client.TcpSocketClient Maven / Gradle / Ivy
package com.iteaj.iot.client;
import com.iteaj.iot.CoreConst;
import com.iteaj.iot.client.component.TcpClientComponent;
import com.iteaj.iot.codec.SocketMessageDecoder;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.concurrent.TimeUnit;
import static com.iteaj.iot.CoreConst.*;
/**
* create time: 2021/8/6
*
* @author iteaj
* @since 1.0
*/
public abstract class TcpSocketClient extends SocketClient {
public TcpSocketClient(TcpClientComponent clientComponent, ClientConnectProperties config) {
super(clientComponent, config);
}
@Override
protected Class extends Channel> channel() {
return NioSocketChannel.class;
}
@Override
public TcpClientComponent getClientComponent() {
return (TcpClientComponent) super.getClientComponent();
}
/**
* 新增连接超时校验
* @param channel
*/
@Override
protected void doInitChannel(Channel channel) {
if(getConfig().getReaderIdleTime() > 0 || getConfig().getReaderIdleTime() > 0
|| getConfig().getAllIdleTime() > 0) {
// 连接超时处理
channel.pipeline().addAfter(CLIENT_ENCODER_HANDLER, IDLE_STATE_EVENT_HANDLER, initIdleStateHandler(getConfig()));
}
}
/**
* 初始化空闲时间监听handler
* @param properties
* @return
*/
protected IdleStateHandler initIdleStateHandler(ClientConnectProperties properties) {
return new IdleStateHandlerAdapter(properties.getReaderIdleTime()
, properties.getWriterIdleTime()
, properties.getAllIdleTime()
, TimeUnit.SECONDS);
}
public class IdleStateHandlerAdapter extends IdleStateHandler {
public IdleStateHandlerAdapter(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
super(readerIdleTime, writerIdleTime, allIdleTime, unit);
}
@Override
protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
ClientConnectProperties config = ctx.channel().attr(CoreConst.CLIENT_KEY).get();
Object idle = getClientComponent().idle(config.connectKey(), evt.state());
if(idle instanceof IdleState) { // 返回超时状态直接关闭连接
long timeout = idle == IdleState.ALL_IDLE ? config.getAllIdleTime() :
idle == IdleState.READER_IDLE ? config.getReaderIdleTime() :
config.getWriterIdleTime();
// 声明连接关闭是因为客户端超时导致
ctx.channel().attr(CoreConst.CLIENT_TIMEOUT_CLOSED).set(timeout);
ctx.channel().close();
} else if(idle != null){ // 返回值不为空则直接写出
writeAndFlush(idle);
} else {
// 什么都不做
}
ctx.fireUserEventTriggered(evt);
}
}
/**
* @see SocketMessageDecoder 基于netty的常用tcp解码器适配
* @return
*/
@Override
protected abstract ChannelInboundHandler createProtocolDecoder();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy