‘liusuyi’
2023-12-04 6474b923d8f6d8ea5e5b63277f18335136c7e33c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.ard.utils.tcp;
 
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.service.IArdEquipRadarService;
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.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
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 {
    @Resource
    IArdEquipRadarService ardEquipRadarService;
 
    @Value("${spring.netty.tcp.enabled}")
    private Boolean tcpClientEnable;
 
    private static List<Channel> serverChannels = new ArrayList<>();
    public static ConcurrentHashMap<Channel, ArdEquipRadar> 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 (!tcpClientEnable) {
            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<ArdEquipRadar> 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);
        }
    }
}