package com.ard.work.component.netty; import com.ard.work.config.TyConfiguration; import com.ard.work.domain.cache.TyTcpServerCache; import com.ard.work.component.netty.handler.ClientHandler; import com.ard.work.component.netty.handler.MessageProtocolDecoder; import com.ard.work.component.netty.handler.MessageProtocolEncoder; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.timeout.IdleStateHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @Component @Slf4j public class NettyTcpClient { public static Map channels = new HashMap<>(); EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); @Resource private TyConfiguration tyConfiguration; @Resource ClientHandler clientHandler; /** * 初始化Bootstrap */ private Bootstrap getBootstrap() { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.SO_KEEPALIVE, true) .handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); pipeline.addLast("heart", new IdleStateHandler(0, 3, 0, TimeUnit.SECONDS)); pipeline.addLast("encoder", new MessageProtocolEncoder()); pipeline.addLast("decoder", new MessageProtocolDecoder()); pipeline.addLast("handler", clientHandler); } }); System.out.println("客户端 ok 。。。 "); return bootstrap; } /** * 初始化连接 */ public void initConnection(String host, Integer port) { log.info("初始化连接TCP服务器【{}:{}】", host, port); String clientId = "clientId_1"; //判断是否已经存在连接,如果存在则关闭之前的连接 if (channels.containsKey(host + ":" + port)) { clientId = channels.get(host + ":" + port).getClientId(); channels.get(host + ":" + port).getChannelFuture().channel().close(); } //异步连接tcp服务端 Bootstrap bootstrap = getBootstrap(); ChannelFuture future = bootstrap.connect(host, port).addListener((ChannelFuture futureListener) -> { if (futureListener.isSuccess()) { log.info("连接TCP服务器成功【{}:{}】", host, port); TyTcpServerCache.putTcpServerCache(host + ":" + port, true); } else { final EventLoop eventLoop = futureListener.channel().eventLoop(); eventLoop.schedule(() -> { log.info("连接TCP服务器失败【{}:{}】,正尝试重连...", host, port); TyTcpServerCache.putTcpServerCache(host + ":" + port, false); try { initConnection(host, port); } catch (Exception e) { e.printStackTrace(); } }, 10, TimeUnit.SECONDS); } }); //将连接存入集合 channels.put(host + ":" + port, TcpClientSession.builder().ClientId(clientId).channelFuture(future).isReConnect(!clientId.isEmpty()).build()); } //创建天宇连接 @PostConstruct public void createTyConnect() { try { initConnection(tyConfiguration.getTcpserver(), tyConfiguration.getTcpport()); } catch (Exception e) { log.error("创建TCP连接异常:{}", e.getMessage()); } } }