‘liusuyi’
2023-12-28 8f224dbf1a1bd1a65dead7ceda8dd0a3fa567115
优化雷达tcp客户端
已重命名1个文件
已修改3个文件
已删除10个文件
1451 ■■■■■ 文件已修改
src/main/java/com/ard/alarm/radar/controller/RadarController.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyChannelInboundHandlerAdapter.java 439 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyChannelInitializer.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyClient.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyClientChannel.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyClientChannelCache.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/BootNettyClientThread.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/ClientHandler.java 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/ClientHelper.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/ClientInitialize.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/DynamicClient.java 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/DynamicClientHandler.java 436 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/DynamicClientInitializer.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/MessageHandler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/radar/controller/RadarController.java
@@ -41,39 +41,38 @@
        if (ardEquipRadar == null) {
            return AjaxResult.error("雷达不存在");
        }
        Channel channel = (Channel)ClientInitialize.SuccessConnectMap.get(ardEquipRadar.getId());
        if (channel==null)
        {
        Channel channel = ClientInitialize.SucChannelMap.get(ardEquipRadar.getIp() + ":" + ardEquipRadar.getPort());
        if (channel == null) {
            return AjaxResult.error("雷达未连接");
        }
        Double longitude = ardEquipRadar.getLongitude();//雷达经度
        Double latitude = ardEquipRadar.getLatitude();//雷达纬度
        Double altitude = ardEquipRadar.getAltitude();//雷达高度
        //计算水平角度
        float p = (float)GisUtils.getNorthAngle(longitude, latitude, targetPosition[0], targetPosition[1]);
        float p = (float) GisUtils.getNorthAngle(longitude, latitude, targetPosition[0], targetPosition[1]);
        //计算垂直角度
        double[] radarPosition = new double[2];
        radarPosition[0] = longitude;
        radarPosition[1] = latitude;
        double distance = GisUtils.getDistance(radarPosition, targetPosition);
        float angleInRadians = (float)Math.atan(distance / altitude);
        float t = (90-(float)Math.toDegrees(angleInRadians))*-1;
        log.debug("distance:"+distance);
        log.debug("p:"+p);
        log.debug("t:"+t);
        float angleInRadians = (float) Math.atan(distance / altitude);
        float t = (90 - (float) Math.toDegrees(angleInRadians)) * -1;
        log.debug("distance:" + distance);
        log.debug("p:" + p);
        log.debug("t:" + t);
        //发送告警前端的角度提示
        byte[] header = {0x01, 0x02, 0x01};//包头
        byte[] payloadHeader = {0x10, 0x03, 0x20, 0x00};//负载头
        byte[] distanceBytes = ByteUtils.decimalToBytes((int)distance);
        distanceBytes=ByteUtils.toLittleEndian(distanceBytes);
        byte[] distanceBytes = ByteUtils.decimalToBytes((int) distance);
        distanceBytes = ByteUtils.toLittleEndian(distanceBytes);
        byte[] pBytes = ByteUtils.floatToBytes(p);
        pBytes=ByteUtils.toLittleEndian(pBytes);
        pBytes = ByteUtils.toLittleEndian(pBytes);
        byte[] tBytes = ByteUtils.floatToBytes(t);
        tBytes=ByteUtils.toLittleEndian(tBytes);
        byte[] resBytes=new byte[20];
        byte[] payloadBody = ByteUtils.appendArrays(distanceBytes,pBytes,tBytes,resBytes);//负载
        tBytes = ByteUtils.toLittleEndian(tBytes);
        byte[] resBytes = new byte[20];
        byte[] payloadBody = ByteUtils.appendArrays(distanceBytes, pBytes, tBytes, resBytes);//负载
        byte[] payload = ByteUtils.appendArrays(payloadHeader,payloadBody);//负载头+负载
        byte[] payload = ByteUtils.appendArrays(payloadHeader, payloadBody);//负载头+负载
        byte[] payloadCrc32 = ByteUtils.parseCrc32(payload);//负载头+负载的crc32校验
        byte[] footer = {0x01, 0x02, 0x00};//包尾
        byte[] data = ByteUtils.appendArrays(header, payload, payloadCrc32, footer);
src/main/java/com/ard/utils/netty/tcp/BootNettyChannelInboundHandlerAdapter.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/BootNettyChannelInitializer.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/BootNettyClient.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/BootNettyClientChannel.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/BootNettyClientChannelCache.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/BootNettyClientThread.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/ClientHandler.java
@@ -8,7 +8,6 @@
import com.ard.utils.util.GisUtils;
import com.ard.utils.mqtt.MqttProducer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.SimpleChannelInboundHandler;
@@ -17,7 +16,6 @@
import javax.xml.bind.DatatypeConverter;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ScheduledFuture;
@@ -58,19 +56,19 @@
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ChannelId id = ctx.channel().id();
        InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        int port = ipSocket.getPort();
        String host = ipSocket.getHostString();
        log.error("与设备" + host + ":" + port + "连接断开!");
        ArdEquipRadar ardEquipRadar = ClientInitialize.tureConnectMap.get(host+ ":" + port);
        String ipPort = ipSocket.getHostString() + ":" + ipSocket.getPort();
        log.error("与设备" + ipPort + "连接断开!");
        // è¿žæŽ¥æ–­å¼€åŽçš„æœ€åŽå¤„理
        ctx.pipeline().remove(this);
        ctx.deregister();
        ctx.close();
        // å°†å¤±è´¥ä¿¡æ¯æ’å…¥Set集合
        ClientInitialize.falseConnectSet.add(ardEquipRadar);
        ArdEquipRadar radar = ClientInitialize.trueConnectMap.get(ipPort);
        if (radar != null) {
            ClientInitialize.falseConnectSet.add(radar);
            ClientInitialize.trueConnectMap.remove(ipPort);
        }
        super.channelInactive(ctx);
    }
@@ -83,20 +81,26 @@
     * @throws Exception
     */
    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
        InetSocketAddress ipSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        int port = ipSocket.getPort();
        String host = ipSocket.getHostString();
        ArdEquipRadar ardEquipRadar = ClientInitialize.tureConnectMap.get(host+":"+port);
        MessageParsing messageParsing = ClientInitialize.MessageMap.get(host + ":" + port);
        String ipPort = ipSocket.getHostString() + ":" + ipSocket.getPort();
        ArdEquipRadar radar = ClientInitialize.trueConnectMap.get(ipPort);
        if (radar == null) {
            return;
        }
        MessageHandler messageHandler = ClientInitialize.SucMessageHandlerMap.get(ipPort);
        if (messageHandler == null) {
            return;
        }
        // å¤„理接收到的消息
        byte[] byteArray = new byte[msg.readableBytes()];
        msg.getBytes(msg.readerIndex(), byteArray);
        byte[] bytes = messageParsing.receiveCompletePacket(byteArray);
        byte[] bytes = messageHandler.receiveCompletePacket(byteArray);
        if (bytes != null) {
            processData(ardEquipRadar, bytes);
            processData(radar, bytes);
        }
    }
    /**
     * é€šé“数据处理完成
@@ -148,7 +152,7 @@
            byte[] payloadCrc32 = ByteUtils.parseCrc32(payload);
            byte[] footer = {0x01, 0x02, 0x00};
            byte[] heart = ByteUtils.appendArrays(header, payload, payloadCrc32, footer);
//            byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00};
            //byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00};
            String hexString = DatatypeConverter.printHexBinary(heart);
            // log.debug("发送心跳:" + hexString);
            message.writeBytes(heart);
@@ -170,15 +174,15 @@
    /**
     * è§£æžæŠ¥è­¦æ•°æ®
     */
    public void processData(ArdEquipRadar ardEquipRadarbyte, byte[] data) {
    public void processData(ArdEquipRadar radar, byte[] data) {
        try {
            String radarId = ardEquipRadarbyte.getId();
            String radarName = ardEquipRadarbyte.getName();
            Double radarLongitude = ardEquipRadarbyte.getLongitude();
            Double radarLagitude = ardEquipRadarbyte.getLatitude();
            Double radarAltitude = ardEquipRadarbyte.getAltitude();
            String radarId = radar.getId();
            String radarName = radar.getName();
            Double radarLongitude = radar.getLongitude();
            Double radarLagitude = radar.getLatitude();
            Double radarAltitude = radar.getAltitude();
            //region crc校验-目前仅用于显示校验结果
            Boolean crc32Check = MessageParsing.CRC32Check(data);
            Boolean crc32Check = MessageHandler.CRC32Check(data);
            if (!crc32Check) {
                log.debug("CRC32校验不通过");
            } else {
@@ -187,12 +191,12 @@
            //endregion
            //log.info("原始数据:" + DatatypeConverter.printHexBinary(data));
            //log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
            data = MessageParsing.transferData(data);//去掉包头和包尾、校验及转义
            data = MessageHandler.transferData(data);//去掉包头和包尾、校验及转义
            //region è´Ÿè½½å¤´è§£æž
            byte[] type = Arrays.copyOfRange(data, 0, 1);//命令类型
            //  log.info("命令类型:" + DatatypeConverter.printHexBinary(type));
            byte[] cmdId = Arrays.copyOfRange(data, 1, 2);//命令ID
            String cmdIdStr=DatatypeConverter.printHexBinary(cmdId);
            String cmdIdStr = DatatypeConverter.printHexBinary(cmdId);
            //log.info("命令ID:" + DatatypeConverter.printHexBinary(cmdId));
            byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//有效负载大小
            payloadSize = toLittleEndian(payloadSize);
@@ -206,7 +210,7 @@
            List<ArdAlarmRadar> well = new ArrayList<>();
            String alarmTime = "";
            Integer targetNum = 0;
            log.debug("处理雷达"+radarName+"数据-->命令ID:"+cmdIdStr);
            log.debug("处理雷达" + radarName + "数据-->命令ID:" + cmdIdStr);
            //雷达移动防火报警
            if (Arrays.equals(cmdId, new byte[]{0x01})) {
                //region å‘Šè­¦ä¿¡æ¯åé¦ˆ
@@ -315,15 +319,14 @@
                    double thetaRadians = Math.toRadians(fTy + 90);
                    // ä½¿ç”¨æ­£å¼¦å‡½æ•°è®¡ç®—对边长度
                    Distance = Math.sin(thetaRadians) * Distance;
                    if(Distance<0)
                    {
                    if (Distance < 0) {
                        continue;//过滤距离小于0的脏数据
                    }
                    //log.debug("目标投影距离(m):" + Distance);
                    Double[] radarXY = {radarLongitude, radarLagitude};
                    Double[] alarmXY = GisUtils.CalculateCoordinates(radarXY, Distance, (double) fTx);
                    log.debug("报警信息:" + "【radarName】" + radarName + "【targetId】"+ targetId  + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime + "【name】" + alarmPointName+"【Distance】"+Distance);
                    log.debug("报警信息:" + "【radarName】" + radarName + "【targetId】" + targetId + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime + "【name】" + alarmPointName + "【Distance】" + Distance);
                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
                    ardAlarmRadar.setTargetId(targetId);
                    ardAlarmRadar.setName(alarmPointName);
@@ -350,7 +353,7 @@
                radarAlarmData.setAlarmTime(alarmTime);
                radarAlarmData.setArdAlarmRadars(radarAlarmInfos);
                MqttProducer.publish(2, false, "radar", JSON.toJSONString(radarAlarmData));
                if (radarFollowInfos.size() >0) {
                if (radarFollowInfos.size() > 0) {
                    radarAlarmData.setArdFollowRadars(radarFollowInfos);
                    //当前雷达扫描存在引导跟踪数据,只保留最后一次锁定的数据
                    MqttProducer.publish(2, false, "radarFollowGuide", JSON.toJSONString(radarAlarmData));
@@ -437,7 +440,7 @@
                        //log.info("所属告警区域名称:" + DatatypeConverter.printHexBinary(szName));
                        String alarmPointName = ByteUtils.bytesToStringZh(szName);
                        // log.info("所属告警区域名称:" + alarmPointName);
                        log.debug("报警信息:"+ "【radarName】" + radarName + "【targetId】" + targetId + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime);
                        log.debug("报警信息:" + "【radarName】" + radarName + "【targetId】" + targetId + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime);
                        ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
                        ardAlarmRadar.setTargetId(targetId);
                        ardAlarmRadar.setName(alarmPointName);
src/main/java/com/ard/utils/netty/tcp/ClientHelper.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/ClientInitialize.java
@@ -1,13 +1,5 @@
package com.ard.utils.netty.tcp;
/**
 * @Description:
 * @ClassName: init
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´07月05日13:11
 * @Version: 1.0
 **/
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.service.IArdEquipRadarService;
import com.ard.utils.netty.config.NettyTcpConfiguration;
@@ -37,17 +29,18 @@
@Component
@Slf4j(topic = "netty")
@Order(2)
public class ClientInitialize implements ApplicationRunner{
public class ClientInitialize implements ApplicationRunner {
    @Resource
    NettyTcpConfiguration nettyTcpConfig;
    @Resource
    IArdEquipRadarService ardEquipRadarService;
    private Bootstrap bootstrap;
    public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();
    public static ConcurrentHashMap<String, ArdEquipRadar> tureConnectMap = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, Object> SuccessConnectMap = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, MessageParsing> MessageMap = new ConcurrentHashMap();
    public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();//失败连接的雷达Set
    public static ConcurrentHashMap<String, ArdEquipRadar> trueConnectMap = new ConcurrentHashMap();//成功连接的ip端口对应的雷达
    public static ConcurrentHashMap<String, MessageHandler> SucMessageHandlerMap = new ConcurrentHashMap();//成功连接的ip端口对应的报文解析器
    public static ConcurrentHashMap<String, Channel> SucChannelMap = new ConcurrentHashMap();//成功连接的ip端口对应的netty通道
    /**
     * Netty初始化配置
     */
@@ -65,7 +58,7 @@
                    }
                });
        // å¼‚步持续监听连接失败的地址
        //异步持续监听连接失败的地址
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
@@ -75,8 +68,8 @@
                            // å¾ªçŽ¯é›†åˆå†…å…ƒç´ 
                            falseConnectSet.forEach(new Consumer<ArdEquipRadar>() {
                                @Override
                                public void accept(ArdEquipRadar ardEquipRadar) {
                                    connectServer(ardEquipRadar);
                                public void accept(ArdEquipRadar radar) {
                                    connectServer(radar);
                                }
                            });
                        }
@@ -99,24 +92,23 @@
        // èŽ·å–åœ°å€åŠç«¯å£
        String host = ardEquipRadar.getIp();
        Integer port = ardEquipRadar.getPort();
        String ipPort = host + ":" + port;
        // å¼‚步连接tcp服务端
        bootstrap.remoteAddress(host, port).connect().addListener((ChannelFuture futureListener) -> {
            if (!futureListener.isSuccess()) {
                log.debug("雷达【" + host + ":" + port + "】连接失败");
                futureListener.channel().close();
                // è¿žæŽ¥å¤±è´¥ä¿¡æ¯æ’å…¥Set
                falseConnectSet.add(ardEquipRadar);
                // è¿žæŽ¥å¤±è´¥ä¿¡æ¯ä»Žmap移除
                tureConnectMap.remove( host + ":" + port);
                SuccessConnectMap.remove(ardEquipRadar.getId());
            } else {
                log.debug("雷达【" + host + ":" + port + "】连接成功");
            if (futureListener.isSuccess()) {
                log.debug("雷达【" + ipPort + "】连接成功");
                // è¿žæŽ¥æˆåŠŸä¿¡æ¯ä»ŽSet拔除
                falseConnectSet.remove(ardEquipRadar);
                // è¿žæŽ¥æˆåŠŸä¿¡æ¯å†™å…¥map
                tureConnectMap.put(host+":"+port, ardEquipRadar);
                MessageMap.put(host+":"+port,new MessageParsing());
                SuccessConnectMap.put(ardEquipRadar.getId(),futureListener.channel());
                trueConnectMap.put(ipPort, ardEquipRadar);
                SucMessageHandlerMap.put(ipPort, new MessageHandler());
                SucChannelMap.put(ipPort, futureListener.channel());
            } else {
                log.debug("雷达【" + ipPort + "】连接失败");
                futureListener.channel().close();
                // è¿žæŽ¥å¤±è´¥ä¿¡æ¯æ’å…¥Set
                falseConnectSet.add(ardEquipRadar);
            }
        });
    }
@@ -134,7 +126,7 @@
        for (ArdEquipRadar ardEquipRadar : ardEquipRadars) {
            String host = ardEquipRadar.getIp();
            Integer port = Integer.valueOf(ardEquipRadar.getPort());
            log.debug("TCP client try to connect radar【" + host + ":" + port+"】");
            log.debug("TCP client try to connect radar【" + host + ":" + port + "】");
            connectServer(ardEquipRadar);//连接每一个雷达服务
        }
    }
src/main/java/com/ard/utils/netty/tcp/DynamicClient.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/DynamicClientHandler.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/DynamicClientInitializer.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/netty/tcp/MessageHandler.java
ÎļþÃû´Ó src/main/java/com/ard/utils/netty/tcp/MessageParsing.java ÐÞ¸Ä
@@ -14,7 +14,7 @@
 * @Date: 2023å¹´07月03日15:30
 * @Version: 1.0
 **/
public class MessageParsing {
public class MessageHandler {
    // åˆ›å»ºç¼“冲区列表
    private List<Byte> buffer = new ArrayList<>();