package com.ard.tianyu.netty.handler; import com.ard.tianyu.netty.TyNettyTcpClient; import com.ard.tianyu.netty.command.BaseCmd; import com.ard.tianyu.service.ITyService; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; @Component @Slf4j @ChannelHandler.Sharable public class ClientHandler extends SimpleChannelInboundHandler { @Resource private ITyService tyService; @Resource private TyNettyTcpClient tyNettyTcpClient; @Override public void channelRead0(ChannelHandlerContext ctx, BaseCmd command) { InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress(); String host = ipSocket.getHostString(); int port = ipSocket.getPort(); tyService.processMessage(host + ":" + port, command); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { //当客户端connect成功后,可以在最后一个handler等待用户输入 log.info("连接成功建立!"); tyService.registerMessage(); super.channelActive(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { log.error("发生异常: ", cause); // 使用日志记录异常 ctx.close(); } @Override public void userEventTriggered(ChannelHandlerContext ctx, Object obj) { if (obj instanceof IdleStateEvent) { IdleStateEvent event = (IdleStateEvent) obj; if (event.state() == IdleState.READER_IDLE) { log.info("客户端读超时"); } else if (event.state() == IdleState.WRITER_IDLE) { // log.info("写空闲发送⼼跳!"); // HeartbeatCommand msg = new HeartbeatCommand(System.currentTimeMillis()); //ctx.writeAndFlush(msg); } else if (event.state() == IdleState.ALL_IDLE) { log.info("客户端所有操作超时"); } } } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress(); int port = ipSocket.getPort(); String host = ipSocket.getHostString(); log.error("与天宇服务{}:{}连接断开!", host, port); ctx.channel().eventLoop().schedule(() -> { log.error("天宇服务端链接不上,开始重连操作..."); try { tyNettyTcpClient.initConnection(host, port); } catch (Exception e) { log.error("天宇服务端连接异常: {}", e.getMessage()); } }, 5, TimeUnit.SECONDS); super.channelInactive(ctx); } }