package com.ard.utils.netty.tcp; import com.ard.alarm.radar.domain.ArdEquipRadar; import com.ard.alarm.radar.service.IArdEquipRadarService; import com.ard.utils.netty.config.NettyTcpConfiguration; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** * @Description: 雷达动态tcp客户端(备用) * @ClassName: DynamicClient * @Author: 刘苏义 * @Date: 2023年11月30日9:25:48 **/ @Slf4j(topic = "netty") @Component public class DynamicClient implements ApplicationRunner { @Resource IArdEquipRadarService ardEquipRadarService; @Resource NettyTcpConfiguration nettyTcpConfig; private static List serverChannels = new ArrayList<>(); public static ConcurrentHashMap ConnectMap = new ConcurrentHashMap(); public static void main(String[] args) throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.SO_KEEPALIVE, true) .handler(new DynamicClientInitializer()); DynamicClient dynamicClient = new DynamicClient(); ArdEquipRadar radar1 = new ArdEquipRadar(); radar1.setName("511"); radar1.setIp("112.98.126.2"); radar1.setPort(1200); dynamicClient.connect(bootstrap, radar1); Thread.sleep(2000); // 等待连接建立 // 模拟动态增加一个服务端 ArdEquipRadar radar2 = new ArdEquipRadar(); radar2.setName("140"); radar2.setIp("112.98.126.2"); radar2.setPort(1201); dynamicClient.connect(bootstrap, radar2); } public void connectToServer(ArdEquipRadar radar) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.SO_KEEPALIVE, true) .handler(new DynamicClientInitializer()); // 连接服务端 ChannelFuture channelFuture = bootstrap.connect(radar.getIp(), radar.getPort()).sync(); Channel serverChannel = channelFuture.channel(); // 将连接的服务端 Channel 添加到管理列表 serverChannels.add(serverChannel); ConnectMap.put(serverChannel, radar); log.debug("雷达【" + radar.getIp() + ":" + radar.getPort() + "】连接成功"); } catch (Exception e) { e.printStackTrace(); } } public Channel connect(Bootstrap bootstrap, ArdEquipRadar radar) { ChannelFuture future = bootstrap.connect(radar.getIp(), radar.getPort()); future.addListener((ChannelFutureListener) futureListener -> { if (futureListener.isSuccess()) { log.info("Connected to radar device: " + radar.getName() + "【" + radar.getIp() + ":" + radar.getPort() + "】" + " successful"); // 在连接建立后,你可以在这里添加业务逻辑或其他处理 serverChannels.add(future.channel()); ConnectMap.put(future.channel(), radar); } else { log.error("Connection to radar device " + radar.getName() + "【" + radar.getIp() + ":" + radar.getPort() + "】" + " failed. Retrying..."); // 连接失败时,定时进行重连 futureListener.channel().eventLoop().schedule( () -> connect(bootstrap, radar), 1L, TimeUnit.SECONDS ); } }); return future.channel(); } // 在连接建立后可以通过调用这个方法向指定的服务端发送数据 public void sendDataToServer(Channel serverChannel, Object data) { serverChannel.writeAndFlush(data); } // 关闭指定的服务端连接 public void closeServerConnection(Channel serverChannel) { serverChannel.close(); serverChannels.remove(serverChannel); } // 关闭所有服务端连接 public void closeAllServerConnections() { for (Channel serverChannel : serverChannels) { serverChannel.close(); } serverChannels.clear(); } /** * 初始化方法 */ @Override public void run(ApplicationArguments args) { if (!nettyTcpConfig.getEnabled()) { return; } EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .option(ChannelOption.SO_KEEPALIVE, true) .handler(new DynamicClientInitializer()); List ardEquipRadars = ardEquipRadarService.selectArdEquipRadarList(new ArdEquipRadar()); for (ArdEquipRadar ardEquipRadar : ardEquipRadars) { String host = ardEquipRadar.getIp(); Integer port = Integer.valueOf(ardEquipRadar.getPort()); log.debug("TCP client try to connect radar【:" + host + ":" + port+"】"); // connectServer(ardEquipRadar);//连接每一个雷达服务 connect(bootstrap, ardEquipRadar); } } }