From 1fd64b07ddb99c2d9cc8a358b71aceb6a2c81492 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: Wed, 05 Jul 2023 15:58:31 +0800
Subject: [PATCH] 修改nettyTCP客户端断开重连 增加数据库连接池 修改日志打印

---
 src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java |   23 -
 src/main/java/com/ard/utils/tcp/ClientHandler.java                           |  444 +++++++++++++++++++++++
 src/main/java/com/ard/config/DruidConfig.java                                |   49 ++
 src/main/java/com/ard/utils/hiksdk/domain/alarmEventInfo.java                |    2 
 pom.xml                                                                      |   19 
 src/main/java/com/ard/utils/ByteUtils.java                                   |  108 +++++
 src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HIKSDKStructure.java      |    2 
 src/main/java/com/ard/utils/hiksdk/domain/recordInfo.java                    |    2 
 src/main/java/com/ard/utils/hiksdk/util/minio/MinioUtils.java                |    2 
 src/main/java/com/ard/utils/SpringTool.java                                  |   18 
 src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java                |    2 
 src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HCNetSDK.java             |    3 
 src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java   |    2 
 src/main/java/com/ard/utils/mqtt/MqttConsumer.java                           |    4 
 src/main/java/com/ard/utils/tcp/MessageParsing.java                          |   38 +
 src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java               |    2 
 src/main/java/com/ard/utils/hiksdk/util/imageUtil/waterMarkUtil.java         |    2 
 src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java     |    6 
 src/main/resources/logback-spring.xml                                        |   50 ++
 src/main/java/com/ard/config/AsyncConfiguration.java                         |    4 
 src/main/java/com/ard/utils/udp/NettyUdpServer.java                          |    5 
 src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java           |   10 
 src/main/java/com/ard/utils/tcp/NettyTcpClient.java                          |    7 
 src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java            |   15 
 src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java                   |   79 ++-
 src/main/java/com/ard/utils/tcp/ClientInitialize.java                        |  136 +++++++
 src/main/resources/application.yml                                           |   35 +
 src/main/java/com/ard/config/MinioClientSingleton.java                       |   32 
 28 files changed, 962 insertions(+), 139 deletions(-)

diff --git a/pom.xml b/pom.xml
index 0244e01..419f554 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,10 +47,7 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-        </dependency>
+
         <!--海康录像机二次开发依赖jar包-->
         <dependency>
             <groupId>net.java.jna</groupId>
@@ -84,6 +81,20 @@
             <artifactId>geodesy</artifactId>
             <version>1.1.3</version>
         </dependency>
+        <!--druid依赖-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java b/src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java
index 1726943..914fd59 100644
--- a/src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java
+++ b/src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java
@@ -4,7 +4,7 @@
 import com.ard.alarm.camera.domain.ArdCameras;
 import com.ard.alarm.camera.mapper.ArdCamerasMapper;
 import com.ard.alarm.camera.service.IArdCamerasService;
-import com.ard.hiksdk.service.impl.HikClientUtil;
+import com.ard.utils.hiksdk.service.impl.HikClientUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
diff --git a/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java b/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
index 2613750..a096f37 100644
--- a/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
+++ b/src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
@@ -4,6 +4,7 @@
 import com.ard.alarm.radar.domain.ArdEquipRadar;
 import com.ard.alarm.radar.mapper.ArdEquipRadarMapper;
 import com.ard.alarm.radar.service.IArdEquipRadarService;
+import com.ard.utils.tcp.ClientInitialize;
 import com.ard.utils.tcp.NettyTcpClient;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,32 +20,10 @@
  * @date 2023-03-11
  */
 @Service
-@Slf4j(topic = "radar")
 public class ArdEquipRadarServiceImpl implements IArdEquipRadarService
 {
     @Autowired
     private ArdEquipRadarMapper ardEquipRadarMapper;
-
-
-    @Resource
-    NettyTcpClient nettyTcpClient;
-    @Value("${spring.netty.tcp.enabled}")
-    private Boolean tcpClientEnable;
-    @PostConstruct
-    public void init() {
-        if(!tcpClientEnable)
-        {
-            return;
-        }
-        List<ArdEquipRadar> ardEquipRadars = selectArdEquipRadarList(new ArdEquipRadar());
-        for (ArdEquipRadar ardEquipRadar:ardEquipRadars)
-        {
-            String host = ardEquipRadar.getIp();
-            Integer port = Integer.valueOf(ardEquipRadar.getPort());
-            log.info("TCP客户端尝试连接:"+host+":"+port);
-            nettyTcpClient.init(ardEquipRadar);
-        }
-    }
 
     /**
      * 查询radar
diff --git a/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java b/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java
index a8243d9..3689447 100644
--- a/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java
+++ b/src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java
@@ -39,7 +39,7 @@
             return;
         }
         nettyUdpServer.init(udpPort);
-        log.info("UDP服务已启动");
+        log.info("管线泄露UDP服务已启动");
     }
 
     @Async("alarm")
diff --git a/src/main/java/com/ard/async/AsyncConfiguration.java b/src/main/java/com/ard/config/AsyncConfiguration.java
similarity index 94%
rename from src/main/java/com/ard/async/AsyncConfiguration.java
rename to src/main/java/com/ard/config/AsyncConfiguration.java
index 0d5c5ec..186acc5 100644
--- a/src/main/java/com/ard/async/AsyncConfiguration.java
+++ b/src/main/java/com/ard/config/AsyncConfiguration.java
@@ -1,4 +1,4 @@
-package com.ard.async;
+package com.ard.config;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -16,7 +16,7 @@
 @EnableAsync(proxyTargetClass = true)
 public class AsyncConfiguration {
     @Bean("alarm")
-    public ThreadPoolTaskExecutor executor(){
+    public ThreadPoolTaskExecutor alarmExecutor(){
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         //配置核心线程数
         executor.setCorePoolSize(15);
diff --git a/src/main/java/com/ard/config/DruidConfig.java b/src/main/java/com/ard/config/DruidConfig.java
new file mode 100644
index 0000000..d1df6c6
--- /dev/null
+++ b/src/main/java/com/ard/config/DruidConfig.java
@@ -0,0 +1,49 @@
+package com.ard.config;
+import com.alibaba.druid.filter.Filter;
+import com.alibaba.druid.filter.stat.StatFilter;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.google.common.collect.Lists;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+/**
+ * @Description: druid连接池的配置,配置如何处理慢sql,
+ * @ClassName: DruidConfig
+ * @Author: 刘苏义
+ * @Date: 2023年07月04日15:29
+ * @Version: 1.0
+ **/
+@Configuration
+public class DruidConfig {
+    //这个注解读取配置文件前缀为prefix的配置,将外部的配置文件与这里绑定
+    @ConfigurationProperties(prefix = "spring.datasource.druid")
+    //容器的开启与关闭
+    @Bean(initMethod = "init",destroyMethod = "close")
+    public DruidDataSource dataSource(){
+        DruidDataSource dataSource=new DruidDataSource();
+        dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
+        return  dataSource;
+    }
+    //bean注解,成为spring的bean,利用filter将慢sql的日志打印出来
+    @Bean
+    public Filter statFilter(){
+        StatFilter statFilter=new StatFilter();
+        //多长时间定义为慢sql,这里定义为5s
+        statFilter.setSlowSqlMillis(5000);
+        //是否打印出慢日志
+        statFilter.setLogSlowSql(true);
+        //是否将日志合并起来
+        statFilter.setMergeSql(true);
+        return  statFilter;
+    }
+    //这是配置druid的监控
+    //这是配置druid的监控与配置文件中功能一样
+    //#stat-view-servlet:
+    //   #enabled:true
+//    @Bean
+//    public ServletRegistrationBean servletRegistrationBean(){
+//        return new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
+//    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ard/config/MinioClientSingleton.java b/src/main/java/com/ard/config/MinioClientSingleton.java
index eaf92cf..713af81 100644
--- a/src/main/java/com/ard/config/MinioClientSingleton.java
+++ b/src/main/java/com/ard/config/MinioClientSingleton.java
@@ -1,12 +1,16 @@
 package com.ard.config;
 
+import com.ard.utils.SpringTool;
 import io.minio.MinioClient;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.context.annotation.Bean;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
+import org.springframework.integration.channel.DefaultHeaderChannelRegistry;
+import org.springframework.integration.channel.PublishSubscribeChannel;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
@@ -31,9 +35,9 @@
     private volatile static MinioClient minioClient;
 
     static {
-        domainUrl = getYmlNew("minio.endpoint");
-        accessKey = getYmlNew("minio.accessKey");
-        secretKey = getYmlNew("minio.secretKey");
+        domainUrl = SpringTool.getYmlInfo("minio.endpoint");
+        accessKey = SpringTool.getYmlInfo("minio.accessKey");
+        secretKey = SpringTool.getYmlInfo("minio.secretKey");
         log.info("minio信息:" + domainUrl + "(" + accessKey + "/" + secretKey + ")");
     }
 
@@ -56,20 +60,14 @@
         return minioClient;
     }
 
-    /*yml配置信息获取*/
-    public static String getYmlNew(String key) {
-        Resource resource = new ClassPathResource("application.yml");
-        Properties properties = null;
-        try {
-            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
-            yamlFactory.setResources(resource);
-            properties = yamlFactory.getObject();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-        return properties.get(key).toString();
-    }
 
+    @Bean
+    public PublishSubscribeChannel errorChannel() {
+        return new PublishSubscribeChannel();
+    }
+    @Bean
+    public DefaultHeaderChannelRegistry integrationHeaderChannelRegistry() {
+        return new DefaultHeaderChannelRegistry();
+    }
 }
 
diff --git a/src/main/java/com/ard/utils/ByteUtils.java b/src/main/java/com/ard/utils/ByteUtils.java
index 507ddcc..33c7856 100644
--- a/src/main/java/com/ard/utils/ByteUtils.java
+++ b/src/main/java/com/ard/utils/ByteUtils.java
@@ -1,10 +1,9 @@
 package com.ard.utils;
 
 import javax.xml.bind.DatatypeConverter;
+import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.zip.CRC32;
 
 /**
  * @Description: 字节工具类
@@ -16,20 +15,20 @@
 public class ByteUtils {
     /**
      * Byte字节转Hex
+     *
      * @param b 字节
      * @return Hex
      */
-    public static String byteToHex(byte b)
-    {
+    public static String byteToHex(byte b) {
         String hexString = Integer.toHexString(b & 0xFF);
         //由于十六进制是由0~9、A~F来表示1~16,所以如果Byte转换成Hex后如果是<16,就会是一个字符(比如A=10),通常是使用两个字符来表示16进制位的,
         //假如一个字符的话,遇到字符串11,这到底是1个字节,还是1和1两个字节,容易混淆,如果是补0,那么1和1补充后就是0101,11就表示纯粹的11
-        if (hexString.length() < 2)
-        {
+        if (hexString.length() < 2) {
             hexString = new StringBuilder(String.valueOf(0)).append(hexString).toString();
         }
         return hexString.toUpperCase();
     }
+
     /**
      * byte数组转float
      */
@@ -37,6 +36,7 @@
         ByteBuffer buffer = ByteBuffer.wrap(bytes);
         return buffer.getFloat();
     }
+
     /**
      * byte数组转整型
      */
@@ -79,4 +79,98 @@
         return littleEndianBytes;
     }
 
+    /**
+     * 小端转大端
+     */
+    public static byte[] toBigEndian(byte[] littleEndianBytes) {
+        byte[] bigEndianBytes = new byte[littleEndianBytes.length];
+        for (int i = 0; i < littleEndianBytes.length; i++) {
+            bigEndianBytes[i] = littleEndianBytes[littleEndianBytes.length - 1 - i];
+        }
+        return bigEndianBytes;
+    }
+
+    /**
+     * int转byte数组
+     */
+    public static byte[] decimalToBytes(int decimalValue) {
+        ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
+        buffer.putInt(decimalValue);
+        return buffer.array();
+    }
+
+    /**
+     * byte数组拼接
+     */
+    public static byte[] appendArrays(byte[]... arrays) {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        try {
+            for (byte[] array : arrays) {
+                outputStream.write(array);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return outputStream.toByteArray();
+    }
+
+    /**
+     * byte数组CRC32校验
+     */
+    public static byte[] parseCrc32(byte[] bytes) {
+        CRC32 crc32 = new CRC32();
+        crc32.update(bytes);
+        bytes = ByteUtils.decimalToBytes((int) crc32.getValue());
+        bytes = ByteUtils.toBigEndian(bytes);
+        // System.out.print("校验:"+DatatypeConverter.printHexBinary(bytes));//打印crc32的校验值
+        return bytes;
+    }
+
+    /**
+     * 去除包头包尾
+     * 刘苏义
+     * 2023/7/4 11:24
+     */
+    public static byte[] removeHeaderAndFooter(byte[] data, int headerLength, int footerLength) {
+        int payloadLength = data.length - headerLength - footerLength;
+        byte[] payload = new byte[payloadLength];
+        System.arraycopy(data, headerLength, payload, 0, payloadLength);
+        return payload;
+    }
+
+    /**
+     * 去除包头包尾crc校验
+     * 刘苏义
+     * 2023/7/4 11:24
+     */
+    public static byte[] removeHeaderFooterAndCRC(byte[] data, int headerLength, int footerLength, int crcLength) {
+        int payloadLength = data.length - headerLength - footerLength - crcLength;
+        byte[] payload = new byte[payloadLength];
+        System.arraycopy(data, headerLength, payload, 0, payloadLength);
+        return payload;
+    }
+
+    /**
+     * 获取后面的字节数组
+     * 刘苏义
+     * 2023/7/4 11:24
+     */
+    public static byte[] getLastBytes(byte[] data, int count) {
+        int startIndex = data.length - count;
+        byte[] lastBytes = new byte[count];
+        System.arraycopy(data, startIndex, lastBytes, 0, count);
+        return lastBytes;
+    }
+
+    /**
+     * 找到00的索引位置
+     */
+    public static int findIndexOfDoubleZero(byte[] bytes) {
+        for (int i = 0; i < bytes.length - 1; i++) {
+            if (bytes[i] == 0x00) {
+                return i;
+            }
+        }
+        return -1;
+    }
 }
diff --git a/src/main/java/com/ard/utils/SpringTool.java b/src/main/java/com/ard/utils/SpringTool.java
index 0a7acfb..123317b 100644
--- a/src/main/java/com/ard/utils/SpringTool.java
+++ b/src/main/java/com/ard/utils/SpringTool.java
@@ -1,11 +1,15 @@
 package com.ard.utils;
 
 import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
 import org.springframework.stereotype.Component;
 
 import java.nio.ByteBuffer;
+import java.util.Properties;
 
 /**
  * @Description:
@@ -36,4 +40,18 @@
         return getApplicationContext().getBean(name);
     }
 
+    /*yml配置信息获取*/
+    public static String getYmlInfo(String key) {
+        Resource resource = new ClassPathResource("application.yml");
+        Properties properties = null;
+        try {
+            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
+            yamlFactory.setResources(resource);
+            properties = yamlFactory.getObject();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        return properties.get(key).toString();
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ard/hiksdk/common/GlobalVariable.java b/src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java
similarity index 93%
rename from src/main/java/com/ard/hiksdk/common/GlobalVariable.java
rename to src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java
index c45d12b..cf3cd15 100644
--- a/src/main/java/com/ard/hiksdk/common/GlobalVariable.java
+++ b/src/main/java/com/ard/utils/hiksdk/common/GlobalVariable.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.common;
+package com.ard.utils.hiksdk.common;
 
 import com.ard.alarm.camera.domain.ArdCameras;
 import lombok.Data;
diff --git a/src/main/java/com/ard/hiksdk/domain/alarmEventInfo.java b/src/main/java/com/ard/utils/hiksdk/domain/alarmEventInfo.java
similarity index 96%
rename from src/main/java/com/ard/hiksdk/domain/alarmEventInfo.java
rename to src/main/java/com/ard/utils/hiksdk/domain/alarmEventInfo.java
index 12ee93f..ff6a06c 100644
--- a/src/main/java/com/ard/hiksdk/domain/alarmEventInfo.java
+++ b/src/main/java/com/ard/utils/hiksdk/domain/alarmEventInfo.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.domain;
+package com.ard.utils.hiksdk.domain;
 
 import lombok.Data;
 
diff --git a/src/main/java/com/ard/hiksdk/domain/recordInfo.java b/src/main/java/com/ard/utils/hiksdk/domain/recordInfo.java
similarity index 90%
rename from src/main/java/com/ard/hiksdk/domain/recordInfo.java
rename to src/main/java/com/ard/utils/hiksdk/domain/recordInfo.java
index 1f5c021..044032c 100644
--- a/src/main/java/com/ard/hiksdk/domain/recordInfo.java
+++ b/src/main/java/com/ard/utils/hiksdk/domain/recordInfo.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.domain;
+package com.ard.utils.hiksdk.domain;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
diff --git a/src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java b/src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java
similarity index 95%
rename from src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
rename to src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java
index 2803831..b2e594c 100644
--- a/src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
+++ b/src/main/java/com/ard/utils/hiksdk/service/impl/FMSGCallBack.java
@@ -1,14 +1,14 @@
-package com.ard.hiksdk.service.impl;
+package com.ard.utils.hiksdk.service.impl;
 
 import com.alibaba.fastjson2.JSON;
 import com.ard.alarm.camera.domain.ArdCameras;
 import com.ard.alarm.camera.domain.CameraCmd;
 import com.ard.alarm.camera.service.impl.ArdCamerasServiceImpl;
 import com.ard.config.MinioClientSingleton;
-import com.ard.hiksdk.common.GlobalVariable;
-import com.ard.hiksdk.domain.alarmEventInfo;
-import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
-import com.ard.hiksdk.util.minio.MinioUtils;
+import com.ard.utils.hiksdk.common.GlobalVariable;
+import com.ard.utils.hiksdk.domain.alarmEventInfo;
+import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK;
+import com.ard.utils.hiksdk.util.minio.MinioUtils;
 import com.ard.utils.DateUtils;
 import com.ard.utils.SpringTool;
 import com.ard.utils.mqtt.MqttConsumer;
@@ -133,7 +133,10 @@
                 publishMqtt(info);
                 break;
             case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
-                log.info("人脸检测事件");
+                log.info("人脸检测事件上报");
+                break;
+            case HCNetSDK.COMM_GISINFO_UPLOAD:
+                log.info("GPS报警信息上报");
                 break;
             default:
                 log.info("未知报警事件类型:lCommand:" + Integer.toHexString(lCommand));
diff --git a/src/main/java/com/ard/hiksdk/service/impl/HikClientUtil.java b/src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java
similarity index 97%
rename from src/main/java/com/ard/hiksdk/service/impl/HikClientUtil.java
rename to src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java
index d0fb7f6..7ace4c1 100644
--- a/src/main/java/com/ard/hiksdk/service/impl/HikClientUtil.java
+++ b/src/main/java/com/ard/utils/hiksdk/service/impl/HikClientUtil.java
@@ -1,10 +1,10 @@
-package com.ard.hiksdk.service.impl;
+package com.ard.utils.hiksdk.service.impl;
 
 import com.ard.alarm.camera.domain.ArdCameras;
 import com.ard.alarm.camera.domain.CameraCmd;
-import com.ard.hiksdk.common.GlobalVariable;
-import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
-import com.ard.hiksdk.util.minio.MinioUtils;
+import com.ard.utils.hiksdk.common.GlobalVariable;
+import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK;
+import com.ard.utils.hiksdk.util.minio.MinioUtils;
 import com.sun.jna.Native;
 import com.sun.jna.Platform;
 import com.sun.jna.ptr.IntByReference;
@@ -14,7 +14,7 @@
 import java.nio.ByteBuffer;
 import java.util.*;
 
-import static com.ard.hiksdk.common.GlobalVariable.cameraMap;
+import static com.ard.utils.hiksdk.common.GlobalVariable.cameraMap;
 
 
 /**
diff --git a/src/main/java/com/ard/hiksdk/service/impl/LoginResultCallBack.java b/src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java
similarity index 90%
rename from src/main/java/com/ard/hiksdk/service/impl/LoginResultCallBack.java
rename to src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java
index 589391a..6f52be7 100644
--- a/src/main/java/com/ard/hiksdk/service/impl/LoginResultCallBack.java
+++ b/src/main/java/com/ard/utils/hiksdk/service/impl/LoginResultCallBack.java
@@ -1,8 +1,8 @@
-package com.ard.hiksdk.service.impl;
+package com.ard.utils.hiksdk.service.impl;
 
 import com.ard.alarm.camera.domain.ArdCameras;
-import com.ard.hiksdk.common.GlobalVariable;
-import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
+import com.ard.utils.hiksdk.common.GlobalVariable;
+import com.ard.utils.hiksdk.util.hikSdkUtil.HCNetSDK;
 import com.sun.jna.Pointer;
 import lombok.extern.slf4j.Slf4j;
 
diff --git a/src/main/java/com/ard/hiksdk/util/hikSdkUtil/HCNetSDK.java b/src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HCNetSDK.java
similarity index 99%
rename from src/main/java/com/ard/hiksdk/util/hikSdkUtil/HCNetSDK.java
rename to src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HCNetSDK.java
index bc27556..23a6961 100644
--- a/src/main/java/com/ard/hiksdk/util/hikSdkUtil/HCNetSDK.java
+++ b/src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HCNetSDK.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.util.hikSdkUtil;
+package com.ard.utils.hiksdk.util.hikSdkUtil;
 
 import com.sun.jna.*;
 import com.sun.jna.examples.win32.W32API;
@@ -899,6 +899,7 @@
     public static final int COMM_ALARM_V30 = 0x4000;//9000报警信息主动上传
     public static final int COMM_ALARM_V40 = 0x4007;
     public static final int COMM_ALARM_RULE = 0x1102;//行为分析信息上传
+    public static final int COMM_GISINFO_UPLOAD = 0x4012;//GIS信息上传
     public static final int COMM_ALARM_PDC = 0x1103;//客流量统计报警上传
     public static final int COMM_UPLOAD_PLATE_RESULT = 0x2800;//交通抓拍结果上传
     public static final int COMM_ITS_PLATE_RESULT = 0x3050;//交通抓拍的终端图片上传
diff --git a/src/main/java/com/ard/hiksdk/util/hikSdkUtil/HIKSDKStructure.java b/src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
similarity index 95%
rename from src/main/java/com/ard/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
rename to src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
index 0b853fb..087728e 100644
--- a/src/main/java/com/ard/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
+++ b/src/main/java/com/ard/utils/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.util.hikSdkUtil;
+package com.ard.utils.hiksdk.util.hikSdkUtil;
 
 import com.sun.jna.Structure;
 
diff --git a/src/main/java/com/ard/hiksdk/util/imageUtil/waterMarkUtil.java b/src/main/java/com/ard/utils/hiksdk/util/imageUtil/waterMarkUtil.java
similarity index 98%
rename from src/main/java/com/ard/hiksdk/util/imageUtil/waterMarkUtil.java
rename to src/main/java/com/ard/utils/hiksdk/util/imageUtil/waterMarkUtil.java
index bc6263f..6d8dedb 100644
--- a/src/main/java/com/ard/hiksdk/util/imageUtil/waterMarkUtil.java
+++ b/src/main/java/com/ard/utils/hiksdk/util/imageUtil/waterMarkUtil.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.util.imageUtil;
+package com.ard.utils.hiksdk.util.imageUtil;
 
 /**
  * @ClassName WaterMarkUtil
diff --git a/src/main/java/com/ard/hiksdk/util/minio/MinioUtils.java b/src/main/java/com/ard/utils/hiksdk/util/minio/MinioUtils.java
similarity index 99%
rename from src/main/java/com/ard/hiksdk/util/minio/MinioUtils.java
rename to src/main/java/com/ard/utils/hiksdk/util/minio/MinioUtils.java
index e64662c..9e96035 100644
--- a/src/main/java/com/ard/hiksdk/util/minio/MinioUtils.java
+++ b/src/main/java/com/ard/utils/hiksdk/util/minio/MinioUtils.java
@@ -1,4 +1,4 @@
-package com.ard.hiksdk.util.minio;
+package com.ard.utils.hiksdk.util.minio;
 
 import com.ard.config.MinioClientSingleton;
 import io.minio.*;
diff --git a/src/main/java/com/ard/utils/mqtt/MqttConsumer.java b/src/main/java/com/ard/utils/mqtt/MqttConsumer.java
index ea2b31a..144e233 100644
--- a/src/main/java/com/ard/utils/mqtt/MqttConsumer.java
+++ b/src/main/java/com/ard/utils/mqtt/MqttConsumer.java
@@ -165,9 +165,9 @@
                 log.info("消息发送成功");
             }
         } catch (MqttPersistenceException e) {
-            e.printStackTrace();
+            log.error("mqtt持久异常:" + e.getMessage());
         } catch (MqttException e) {
-            e.printStackTrace();
+            log.error("mqtt异常:" + e.getMessage());
         }
     }
 }
diff --git a/src/main/java/com/ard/utils/tcp/ClientHandler.java b/src/main/java/com/ard/utils/tcp/ClientHandler.java
new file mode 100644
index 0000000..c79496d
--- /dev/null
+++ b/src/main/java/com/ard/utils/tcp/ClientHandler.java
@@ -0,0 +1,444 @@
+package com.ard.utils.tcp;
+
+/**
+ * @Description:
+ * @ClassName: ClientHandler
+ * @Author: 刘苏义
+ * @Date: 2023年07月05日13:13
+ * @Version: 1.0
+ **/
+
+import com.alibaba.fastjson2.JSON;
+import com.ard.alarm.radar.domain.ArdAlarmRadar;
+import com.ard.alarm.radar.domain.ArdEquipRadar;
+import com.ard.alarm.radar.domain.RadarAlarmData;
+import com.ard.utils.ByteUtils;
+import com.ard.utils.GisUtils;
+import com.ard.utils.mqtt.MqttConsumer;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelId;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.xml.bind.DatatypeConverter;
+import java.net.InetSocketAddress;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 客户端处理器
+ *
+ * @author lijiamin
+ */
+@Slf4j(topic = "netty")
+public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
+    private ChannelHandlerContext context;
+    private ScheduledFuture<?> heartbeatTask;
+
+    /**
+     * 连接建立
+     *
+     * @param ctx
+     * @throws Exception
+     */
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        context = ctx;
+        startHeartbeatTask();//开始发送心跳
+    }
+
+    /**
+     * 连接断开
+     *
+     * @param ctx
+     * @throws Exception
+     */
+    @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(id);
+        // 连接断开后的最后处理
+        ctx.pipeline().remove(this);
+        ctx.deregister();
+        ctx.close();
+
+        // 将失败信息插入Set集合
+        ClientInitialize.falseConnectSet.add(ardEquipRadar);
+        super.channelInactive(ctx);
+    }
+
+    /**
+     * 通道数据读取
+     * 业务操作
+     *
+     * @param ctx
+     * @param msg
+     * @throws Exception
+     */
+    @Override
+    public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
+        ChannelId id = ctx.channel().id();
+        ArdEquipRadar ardEquipRadar = ClientInitialize.tureConnectMap.get(id);
+        // 处理接收到的消息
+        byte[] byteArray = new byte[msg.readableBytes()];
+        msg.getBytes(msg.readerIndex(), byteArray);
+        byte[] bytes = MessageParsing.receiveCompletePacket(byteArray);
+        if (bytes != null) {
+            processData(ardEquipRadar, bytes);
+        }
+    }
+
+    /**
+     * 通道数据处理完成
+     *
+     * @param ctx
+     * @throws Exception
+     */
+    @Override
+    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+        super.channelReadComplete(ctx);
+    }
+
+    /**
+     * 事件触发
+     *
+     * @param ctx
+     * @param evt
+     * @throws Exception
+     */
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        super.userEventTriggered(ctx, evt);
+    }
+
+    /**
+     * 异常触发
+     *
+     * @param ctx
+     * @param cause
+     * @throws Exception
+     */
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        // 发生异常时的处理
+        cause.printStackTrace();
+        ctx.close();
+        stopHeartbeatTask();//停止心跳发送
+    }
+
+    /**
+     * 开始心跳任务
+     */
+    private void startHeartbeatTask() {
+        heartbeatTask = context.executor().scheduleAtFixedRate(() -> {
+            // 发送心跳消息
+            ByteBuf message = context.alloc().buffer();
+            byte[] header = {0x01, 0x02, 0x01};
+            byte[] payload = {0x10, 0x00, 0x00, 0x00};
+            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};
+            String hexString = DatatypeConverter.printHexBinary(heart);
+            log.info("发送心跳:" + hexString);
+            message.writeBytes(heart);
+            context.writeAndFlush(message);
+
+        }, 0, 5, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 停止心跳任务
+     */
+    private void stopHeartbeatTask() {
+        if (heartbeatTask != null) {
+            heartbeatTask.cancel(false);
+            heartbeatTask = null;
+        }
+    }
+
+    /**
+     * 解析报警数据
+     */
+    public void processData(ArdEquipRadar ardEquipRadarbyte, byte[] data) {
+        try {
+            String radarId = ardEquipRadarbyte.getId();
+            String radarName = ardEquipRadarbyte.getName();
+            Double radarLongitude = ardEquipRadarbyte.getLongitude();
+            Double radarLagitude = ardEquipRadarbyte.getLatitude();
+            //region crc校验-目前仅用于显示校验结果
+            Boolean crc32Check = MessageParsing.CRC32Check(data);
+            if (!crc32Check) {
+                log.info("CRC32校验不通过");
+            } else {
+                log.info("CRC32校验通过");
+            }
+            //endregion
+            //log.info("原始数据:" + DatatypeConverter.printHexBinary(data));
+            //log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
+            data = MessageParsing.transferData(data);//去掉包头和包尾、校验及转义
+            //region 负载头解析
+            byte[] type = Arrays.copyOfRange(data, 0, 1);//命令类型
+            //  log.info("命令类型:" + DatatypeConverter.printHexBinary(type));
+            byte[] cmdId = Arrays.copyOfRange(data, 1, 2);//命令ID
+            //  log.info("命令ID:" + DatatypeConverter.printHexBinary(cmdId));
+            byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//有效负载大小
+            payloadSize = ByteUtils.toLittleEndian(payloadSize);
+            int payloadSizeToDecimal = ByteUtils.bytesToDecimal(payloadSize);
+            // log.info("有效负载大小(转整型):" + payloadSizeToDecimal);
+            //endregion
+            List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
+            String alarmTime = "";
+            Integer targetNum = 0;
+            if (Arrays.equals(cmdId, new byte[]{0x01})) {
+                //region 告警信息反馈
+                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
+                dwTim = ByteUtils.toLittleEndian(dwTim);
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                long l = ByteUtils.bytesToDecimal(dwTim);
+                alarmTime = sdf.format(l * 1000);
+                // log.info("周视图像的出现时间(转date):" + alarmTime);
+
+                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
+                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                if (targetNum == 0) {
+                    return;
+                }
+                log.info("目标总点数(转整型):" + targetNum);
+
+                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
+                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
+                // log.info("单条报警大小:" + uintSize);
+
+                for (int i = 0; i < targetNum; i++) {
+
+                    Integer index = 68 + uintSize * i;
+                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
+                    // log.info("目标ID:" + DatatypeConverter.printHexBinary(cmdId));
+                    dwID = ByteUtils.toLittleEndian(dwID);
+                    int id = ByteUtils.bytesToDecimal(dwID);
+
+                    // log.info("目标ID号:" + id);
+
+                    byte[] iDistance = Arrays.copyOfRange(data, index + 8, index + 12);
+                    iDistance = ByteUtils.toLittleEndian(iDistance);
+                    Double Distance = ByteUtils.bytesToDouble(iDistance);
+                    // log.info("目标当前距离(m):" + Distance);
+                    //region 不需要的字段
+//                    byte[] dwGSum = Arrays.copyOfRange(data, index + 4, index + 8);
+//                    dwGSum = toLittleEndian(dwGSum);
+//                    int GSum = byteArrayToDecimal(dwGSum);
+//                    log.info("目标当前像素灰度和:" + GSum);
+//                    byte[] iTw = Arrays.copyOfRange(data, index + 12, index + 16);
+//                    iTw = toLittleEndian(iTw);
+//                    int Tw = byteArrayToDecimal(iTw);
+//                    log.info("目标当前的像素宽度:" + Tw);
+//
+//                    byte[] iTh = Arrays.copyOfRange(data, index + 16, index + 20);
+//                    iTh = toLittleEndian(iTh);
+//                    int Th = byteArrayToDecimal(iTh);
+//                    log.info("目标当前的像素高度:" + Th);
+//
+//                    byte[] wPxlArea = Arrays.copyOfRange(data, index + 20, index + 22);
+//                    wPxlArea = toLittleEndian(wPxlArea);
+//                    int PxlArea = byteArrayToDecimal(wPxlArea);
+//                    log.info("目标当前像素面积:" + PxlArea);
+//
+//                    byte[] cTrkNum = Arrays.copyOfRange(data, index + 22, index + 23);
+//                    cTrkNum = toLittleEndian(cTrkNum);
+//                    int TrkNum = byteArrayToDecimal(cTrkNum);
+//                    log.info("轨迹点数:" + TrkNum);
+
+//                    byte[] sVx = Arrays.copyOfRange(data, index + 24, index + 26);
+//                    sVx = toLittleEndian(sVx);
+//                    int Vx = byteArrayToDecimal(sVx);
+//                    log.info("目标当前速度矢量(像素距离)X:" + Vx);
+//
+//                    byte[] sVy = Arrays.copyOfRange(data, index + 26, index + 28);
+//                    sVy = toLittleEndian(sVy);
+//                    int Vy = byteArrayToDecimal(sVy);
+//                    log.info("目标当前速度矢量(像素距离)Y:" + Vy);
+//
+//                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 28, index + 30);
+//                    sAreaNo = toLittleEndian(sAreaNo);
+//                    int AreaNo = byteArrayToDecimal(sAreaNo);
+//                    log.info("目标归属的告警区域号:" + AreaNo);
+//
+//                    byte[] cGrp = Arrays.copyOfRange(data, index + 30, index + 31);
+//                    cGrp = toLittleEndian(cGrp);
+//                    int Grp = byteArrayToDecimal(cGrp);
+//                    log.info("所属组:" + Grp);
+                    //endregion
+                    String alarmType = "";
+                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
+                    cStat = ByteUtils.toLittleEndian(cStat);
+                    String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
+                    // log.info("目标当前状态:" + binaryString);
+                    // 提取第4位至第6位的值
+                    int extractedValue = (cStat[0] >> 4) & 0b00001111;
+                    // 判断提取的值
+                    if (extractedValue == 0b0000) {
+                        alarmType = "运动目标检测";
+                    } else if (extractedValue == 0b0001) {
+                        alarmType = "热源检测";
+                    }
+                    // log.info("报警类型:" + alarmType);
+
+                    byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
+                    int position = ByteUtils.findIndexOfDoubleZero(szName);
+                    String alarmPointName;
+                    if (position != -1) {
+                        byte[] result = new byte[position];
+                        System.arraycopy(szName, 0, result, 0, position);
+                        alarmPointName = new String(result, "GBK");
+                    } else {
+                        alarmPointName = new String(szName, "GBK");
+                    }
+                    // log.info("所属告警区域名称:" + alarmPointName);
+                    byte[] afTx = Arrays.copyOfRange(data, index + 96, index + 100);
+                    afTx = ByteUtils.toLittleEndian(afTx);
+                    float fTx = ByteUtils.bytesToFloat(afTx);
+                    //  log.info("水平角度:" + fTx);
+                    byte[] afTy = Arrays.copyOfRange(data, index + 112, index + 116);
+                    afTy = ByteUtils.toLittleEndian(afTy);
+                    float fTy = ByteUtils.bytesToFloat(afTy);
+                    //  log.info("垂直角度:" + fTy);
+                    Double[] radarXY = {radarLagitude, radarLagitude};
+                    Double[] alarmXY = GisUtils.CalculateCoordinates(radarXY, Distance, (double) fTx);
+                    //  log.info("报警信息:" + "【id】" + id + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime + "【distance】" + Distance + "【P】" + fTx + "【T】" + fTy + "【X】" + alarmXY[0] + "【Y】" + alarmXY[1]);
+                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
+                    ardAlarmRadar.setTargetId(id);
+                    ardAlarmRadar.setName(alarmPointName);
+                    ardAlarmRadar.setLongitude(alarmXY[0]);
+                    ardAlarmRadar.setLatitude(alarmXY[1]);
+                    ardAlarmRadar.setAlarmType(alarmType);
+                    radarAlarmInfos.add(ardAlarmRadar);
+                }
+                //endregion
+            }
+            if (Arrays.equals(cmdId, new byte[]{0x04})) {
+                //region抽油机AI状态反馈
+                String hexString = DatatypeConverter.printHexBinary(data);
+                //log.info(hexString);
+
+                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
+                dwTim = ByteUtils.toLittleEndian(dwTim);
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                long l = ByteUtils.bytesToDecimal(dwTim);
+                alarmTime = sdf.format(l * 1000);
+                //log.info("周视图像的出现时间(转date):" + alarmTime);
+
+                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
+                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                log.info("目标总点数(转整型):" + targetNum);
+                if (targetNum == 0) {
+                    return;
+                }
+                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
+                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
+                //log.info("单条报警大小:" + uintSize);
+                for (int i = 0; i < targetNum; i++) {
+                    Integer index = 68 + uintSize * i;
+                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
+                    //log.info("目标ID:" + DatatypeConverter.printHexBinary(dwID));
+                    dwID = ByteUtils.toLittleEndian(dwID);
+                    int id = ByteUtils.bytesToDecimal(dwID);
+                    //log.info("目标ID号:" + id);
+                    //region 不需要的字段
+                    byte[] iTw = Arrays.copyOfRange(data, index + 4, index + 8);
+                    iTw = ByteUtils.toLittleEndian(iTw);
+                    int Tw = ByteUtils.bytesToDecimal(iTw);
+                    // log.info("目标当前的像素宽度:" + Tw);
+
+                    byte[] iTh = Arrays.copyOfRange(data, index + 8, index + 12);
+                    iTh = ByteUtils.toLittleEndian(iTh);
+                    int Th = ByteUtils.bytesToDecimal(iTh);
+                    //log.info("目标当前的像素高度:" + Th);
+
+                    byte[] fTx = Arrays.copyOfRange(data, index + 12, index + 16);
+                    fTx = ByteUtils.toLittleEndian(fTx);
+                    float fTxAngle = ByteUtils.bytesToFloat(fTx);
+                    //log.info("p角度:" + fTxAngle);
+                    byte[] fTy = Arrays.copyOfRange(data, index + 16, index + 20);
+                    fTy = ByteUtils.toLittleEndian(fTy);
+                    float fTyAngle = ByteUtils.bytesToFloat(fTy);
+                    //log.info("t角度:" + fTyAngle);
+
+                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 20, index + 22);
+                    sAreaNo = ByteUtils.toLittleEndian(sAreaNo);
+                    int AreaNo = ByteUtils.bytesToDecimal(sAreaNo);
+                    //log.info("目标归属的告警区域号:" + AreaNo);
+
+                    byte[] cGrp = Arrays.copyOfRange(data, index + 22, index + 23);
+                    cGrp = ByteUtils.toLittleEndian(cGrp);
+                    int Grp = ByteUtils.bytesToDecimal(cGrp);
+                    //log.info("所属组:" + Grp);
+                    //endregion
+                    String alarmType;
+                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
+                    cStat = ByteUtils.toLittleEndian(cStat);
+                    //String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
+                    //log.info("目标当前状态:" + binaryString);
+                    // 提取第0位值
+                    // 使用位运算操作判断第0位是否为1
+                    boolean isB0 = (cStat[0] & 0x01) == 0x00;
+                    // 判断提取的值
+                    if (isB0) {
+                        alarmType = "雷达抽油机停机";
+                    } else {
+                        continue;
+                    }
+                    //log.info("报警类型:" + alarmType);
+
+                    byte[] szName = Arrays.copyOfRange(data, index + 32, index + 64);
+                    //log.info("所属告警区域名称:" + DatatypeConverter.printHexBinary(szName));
+                    int position = ByteUtils.findIndexOfDoubleZero(szName);
+                    String alarmPointName;
+                    if (position != -1) {
+                        byte[] result = new byte[position];
+                        System.arraycopy(szName, 0, result, 0, position);
+                        alarmPointName = new String(result, "GBK");
+                    } else {
+                        alarmPointName = new String(szName, "GBK");
+                    }
+                    // log.info("所属告警区域名称:" + alarmPointName);
+                    //log.info("报警信息:" + "【id】" + id + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime);
+                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
+                    ardAlarmRadar.setTargetId(id);
+                    ardAlarmRadar.setName(alarmPointName);
+                    ardAlarmRadar.setAlarmType(alarmType);
+                    radarAlarmInfos.add(ardAlarmRadar);
+                }
+                //endregion
+            }
+            if (StringUtils.isEmpty(alarmTime)) {
+                return;
+            }
+            if (targetNum == 0) {
+                return;
+            }
+            RadarAlarmData radarAlarmData = new RadarAlarmData();
+            radarAlarmData.setRadarId(radarId);
+            radarAlarmData.setRadarName(radarName);
+            radarAlarmData.setAlarmTime(alarmTime);
+            radarAlarmData.setArdAlarmRadars(radarAlarmInfos);
+            MqttConsumer.publish(2, false, "radar", JSON.toJSONString(radarAlarmData));
+        } catch (Exception ex) {
+            log.error("雷达报文解析异常:" + ex.getMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/com/ard/utils/tcp/ClientInitialize.java b/src/main/java/com/ard/utils/tcp/ClientInitialize.java
new file mode 100644
index 0000000..0fa3d9e
--- /dev/null
+++ b/src/main/java/com/ard/utils/tcp/ClientInitialize.java
@@ -0,0 +1,136 @@
+package com.ard.utils.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 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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.function.Consumer;
+
+/**
+ * 客户端初始化
+ *
+ * @author lijiamin
+ */
+@Component
+@Slf4j(topic = "netty")
+public class ClientInitialize {
+
+    @Resource
+    IArdEquipRadarService ardEquipRadarService;
+
+    @Value("${spring.netty.tcp.enabled}")
+    private Boolean tcpClientEnable;
+
+    private Bootstrap bootstrap;
+    public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();
+    public static ConcurrentHashMap<ChannelId, ArdEquipRadar> tureConnectMap = new ConcurrentHashMap();
+
+    /**
+     * Netty初始化配置
+     */
+    public void initNettyTcp() {
+        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
+        bootstrap = new Bootstrap();
+        bootstrap.group(eventLoopGroup)
+                .channel(NioSocketChannel.class)
+                .option(ChannelOption.TCP_NODELAY, true)
+                .option(ChannelOption.SO_KEEPALIVE, true)
+                .handler(new ChannelInitializer<SocketChannel>() {
+                    @Override
+                    protected void initChannel(SocketChannel socketChannel) {
+                        socketChannel.pipeline().addLast(new ClientHandler());
+                    }
+                });
+
+        // 异步持续监听连接失败的地址
+        CompletableFuture.runAsync(new Runnable() {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        if (falseConnectSet.size() != 0) {
+                            // 循环集合内元素
+                            falseConnectSet.forEach(new Consumer<ArdEquipRadar>() {
+                                @Override
+                                public void accept(ArdEquipRadar ardEquipRadar) {
+                                    connectServer(ardEquipRadar);
+                                }
+                            });
+                        }
+                        Thread.sleep(3000);
+                    } catch (Exception e) {
+                        log.error("Netty初始化配置监听地址出现异常");
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * 服务连接
+     *
+     * @param ardEquipRadar
+     */
+    public void connectServer(ArdEquipRadar ardEquipRadar) {
+        // 获取地址及端口
+        String host = ardEquipRadar.getIp();
+        Integer port = ardEquipRadar.getPort();
+        // 异步连接tcp服务端
+        bootstrap.remoteAddress(host, port).connect().addListener((ChannelFuture futureListener) -> {
+            if (!futureListener.isSuccess()) {
+                log.error(host + ":" + port + "雷达TCP服务端连接失败");
+                futureListener.channel().close();
+                // 连接失败信息插入Set
+                falseConnectSet.add(ardEquipRadar);
+                // 连接失败信息从map移除
+                tureConnectMap.remove(futureListener.channel().id());
+            } else {
+                log.info(host + ":" + port + "雷达TCP服务端连接成功");
+                // 连接成功信息从Set拔除
+                falseConnectSet.remove(ardEquipRadar);
+                // 连接成功信息写入map
+                tureConnectMap.put(futureListener.channel().id(), ardEquipRadar);
+            }
+        });
+    }
+
+    /**
+     * 初始化方法
+     */
+    @PostConstruct
+    public void initialize() {
+        if (!tcpClientEnable) {
+            return;
+        }
+        initNettyTcp();//初始化nettyTcp
+        List<ArdEquipRadar> ardEquipRadars = ardEquipRadarService.selectArdEquipRadarList(new ArdEquipRadar());
+        for (ArdEquipRadar ardEquipRadar : ardEquipRadars) {
+            String host = ardEquipRadar.getIp();
+            Integer port = Integer.valueOf(ardEquipRadar.getPort());
+            log.info("TCP客户端尝试连接:" + host + ":" + port);
+            connectServer(ardEquipRadar);//连接每一个雷达服务
+        }
+    }
+}
diff --git a/src/main/java/com/ard/utils/tcp/MessageParsing.java b/src/main/java/com/ard/utils/tcp/MessageParsing.java
index 14aa3c5..e468e9d 100644
--- a/src/main/java/com/ard/utils/tcp/MessageParsing.java
+++ b/src/main/java/com/ard/utils/tcp/MessageParsing.java
@@ -1,5 +1,7 @@
 package com.ard.utils.tcp;
 
+import com.ard.utils.ByteUtils;
+
 import javax.xml.bind.DatatypeConverter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -44,6 +46,36 @@
     }
 
     /**
+     * crc32校验检查
+     * 刘苏义
+     * 2023/7/4 11:24
+     */
+    public static Boolean CRC32Check(byte[] packet) {
+        //System.out.println(DatatypeConverter.printHexBinary(packet));
+        int headerLength = 3;//包头3个字节
+        int footerLength = 3;//包尾3个字节
+        int crcLength = 4;//crc校验4个字节
+        //去掉包头包尾
+        byte[] payloadCrc32 = ByteUtils.removeHeaderAndFooter(packet, headerLength, footerLength);
+        //System.out.println(DatatypeConverter.printHexBinary(payloadCrc32));
+        //获取到数据携带的crc32值
+        byte[] oldCrc32 = ByteUtils.getLastBytes(payloadCrc32, crcLength);
+        //去掉包头包尾crc32字节,仅保留负载
+        byte[] payload = ByteUtils.removeHeaderFooterAndCRC(packet, headerLength, footerLength, crcLength);
+       // System.out.println(DatatypeConverter.printHexBinary(payload));
+        //计算负载的crc32值
+        byte[] NewCrc32 = ByteUtils.parseCrc32(payload);
+        System.out.println("old:"+DatatypeConverter.printHexBinary(oldCrc32));
+        System.out.println("new:"+DatatypeConverter.printHexBinary(NewCrc32));
+        //判断数据的crc32校验值和计算值是否相同
+        if (Arrays.equals(oldCrc32, NewCrc32)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
      * 获取包结束索引
      */
     public static int findPacketEndIndex(List<Byte> buffer, byte[] packetEnd) {
@@ -78,8 +110,10 @@
      * 去掉包头和包尾校验及转义
      */
     public static byte[] transferData(byte[] data) {
-        data = Arrays.copyOfRange(data, 3, data.length);
-        data = Arrays.copyOfRange(data, 0, data.length - 7);
+        int headerLength = 3;//包头3个字节
+        int footerLength = 3;//包尾3个字节
+        int crcLength = 4;//crc校验4个字节
+        data= ByteUtils.removeHeaderFooterAndCRC(data,headerLength,footerLength,crcLength);
         String dataStr = DatatypeConverter.printHexBinary(data);
         if (dataStr.contains("01020201")) {//转义01020201
             dataStr = dataStr.replaceAll("01020201", "010201");
diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClient.java b/src/main/java/com/ard/utils/tcp/NettyTcpClient.java
index 2eab8e2..464bba5 100644
--- a/src/main/java/com/ard/utils/tcp/NettyTcpClient.java
+++ b/src/main/java/com/ard/utils/tcp/NettyTcpClient.java
@@ -16,7 +16,7 @@
 import java.util.concurrent.TimeUnit;
 
 /**
- * @Description:
+ * @Description: 另一种tcp客户端 目前弃用
  * @ClassName: NettyTcpClient
  * @Author: 刘苏义
  * @Date: 2023年06月25日17:00
@@ -24,11 +24,10 @@
  **/
 @EnableAsync
 @Component
-@Slf4j(topic = "radar")
+@Slf4j(topic = "netty")
 public class NettyTcpClient {
-    @Async
+    @Async("alarm")
     public void init(ArdEquipRadar ardEquipRadar) {
-
         while (true) {
             NioEventLoopGroup group = new NioEventLoopGroup();
             try {
diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
index fa6016c..37d339e 100644
--- a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
+++ b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
@@ -11,20 +11,22 @@
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import javax.xml.bind.DatatypeConverter;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+
 /**
- * @Description: tcp客户端处理
+ * @Description: tcp客户端处理-弃用
  * @ClassName: NettyTcpClientHandler
  * @Author: 刘苏义
  * @Date: 2023年06月25日17:02
  * @Version: 1.0
  **/
-@Slf4j(topic = "radar")
+@Slf4j(topic = "netty")
 public class NettyTcpClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
 
     private String host;
@@ -72,7 +74,12 @@
         heartbeatTask = context.executor().scheduleAtFixedRate(() -> {
             // 发送心跳消息
             ByteBuf message = context.alloc().buffer();
-            byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00};
+            byte[] header = {0x01, 0x02, 0x01};
+            byte[] payload = {0x10, 0x00, 0x00, 0x00};
+            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};
             String hexString = DatatypeConverter.printHexBinary(heart);
             log.info("发送心跳:" + hexString);
             message.writeBytes(heart);
@@ -105,23 +112,32 @@
      */
     public void processData(byte[] data) {
         try {
+            //region crc校验-目前仅用于显示校验结果
+            Boolean crc32Check = MessageParsing.CRC32Check(data);
+            if (!crc32Check) {
+                log.info("CRC32校验不通过");
+            } else {
+                log.info("CRC32校验通过");
+            }
+            //endregion
             //log.info("原始数据:" + DatatypeConverter.printHexBinary(data));
-            log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
+            //log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
             data = MessageParsing.transferData(data);//去掉包头和包尾、校验及转义
-
+            //region 负载头解析
             byte[] type = Arrays.copyOfRange(data, 0, 1);//命令类型
             //  log.info("命令类型:" + DatatypeConverter.printHexBinary(type));
-
             byte[] cmdId = Arrays.copyOfRange(data, 1, 2);//命令ID
             //  log.info("命令ID:" + DatatypeConverter.printHexBinary(cmdId));
-
             byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//有效负载大小
             payloadSize = ByteUtils.toLittleEndian(payloadSize);
             int payloadSizeToDecimal = ByteUtils.bytesToDecimal(payloadSize);
             // log.info("有效负载大小(转整型):" + payloadSizeToDecimal);
+            //endregion
             List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
-            String alarmTime="";
+            String alarmTime = "";
+            Integer targetNum = 0;
             if (Arrays.equals(cmdId, new byte[]{0x01})) {
+                //region 告警信息反馈
                 byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
                 dwTim = ByteUtils.toLittleEndian(dwTim);
                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -131,8 +147,11 @@
 
                 byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                 wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
-                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
-                //log.info("目标总点数(转整型):" + targetNum);
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                if (targetNum == 0) {
+                    return;
+                }
+                log.info("目标总点数(转整型):" + targetNum);
 
                 //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                 int uintSize = (payloadSizeToDecimal - 64) / targetNum;
@@ -213,7 +232,7 @@
                     // log.info("报警类型:" + alarmType);
 
                     byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
-                    int position = findIndexOfDoubleZero(szName);
+                    int position = ByteUtils.findIndexOfDoubleZero(szName);
                     String alarmPointName;
                     if (position != -1) {
                         byte[] result = new byte[position];
@@ -242,10 +261,11 @@
                     ardAlarmRadar.setAlarmType(alarmType);
                     radarAlarmInfos.add(ardAlarmRadar);
                 }
-
+                //endregion
             }
             if (Arrays.equals(cmdId, new byte[]{0x04})) {
-                //String hexString = DatatypeConverter.printHexBinary(data);
+                //region抽油机AI状态反馈
+                String hexString = DatatypeConverter.printHexBinary(data);
                 //log.info(hexString);
 
                 byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
@@ -257,9 +277,11 @@
 
                 byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                 wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
-                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
-                //log.info("目标总点数(转整型):" + targetNum);
-
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                log.info("目标总点数(转整型):" + targetNum);
+                if (targetNum == 0) {
+                    return;
+                }
                 //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                 int uintSize = (payloadSizeToDecimal - 64) / targetNum;
                 //log.info("单条报警大小:" + uintSize);
@@ -307,9 +329,9 @@
                     //log.info("目标当前状态:" + binaryString);
                     // 提取第0位值
                     // 使用位运算操作判断第0位是否为1
-                    boolean isBitSet = (cStat[0] & 0x01) == 0x00;
+                    boolean isB0 = (cStat[0] & 0x01) == 0x00;
                     // 判断提取的值
-                    if (isBitSet) {
+                    if (isB0) {
                         alarmType = "雷达抽油机停机";
                     } else {
                         continue;
@@ -318,7 +340,7 @@
 
                     byte[] szName = Arrays.copyOfRange(data, index + 32, index + 64);
                     //log.info("所属告警区域名称:" + DatatypeConverter.printHexBinary(szName));
-                    int position = findIndexOfDoubleZero(szName);
+                    int position = ByteUtils.findIndexOfDoubleZero(szName);
                     String alarmPointName;
                     if (position != -1) {
                         byte[] result = new byte[position];
@@ -335,6 +357,13 @@
                     ardAlarmRadar.setAlarmType(alarmType);
                     radarAlarmInfos.add(ardAlarmRadar);
                 }
+                //endregion
+            }
+            if (StringUtils.isEmpty(alarmTime)) {
+                return;
+            }
+            if (targetNum == 0) {
+                return;
             }
             RadarAlarmData radarAlarmData = new RadarAlarmData();
             radarAlarmData.setRadarId(id);
@@ -345,18 +374,6 @@
         } catch (Exception ex) {
             log.error("雷达报文解析异常:" + ex.getMessage());
         }
-    }
-
-    /**
-     * 找到00的索引位置
-     */
-    private int findIndexOfDoubleZero(byte[] bytes) {
-        for (int i = 0; i < bytes.length - 1; i++) {
-            if (bytes[i] == 0x00) {
-                return i;
-            }
-        }
-        return -1;
     }
 
 }
diff --git a/src/main/java/com/ard/utils/udp/NettyUdpServer.java b/src/main/java/com/ard/utils/udp/NettyUdpServer.java
index 724458d..caa5a8e 100644
--- a/src/main/java/com/ard/utils/udp/NettyUdpServer.java
+++ b/src/main/java/com/ard/utils/udp/NettyUdpServer.java
@@ -18,9 +18,8 @@
     /**
      * 启动服务
      */
-    @Async
+    @Async("alarm")
     public void init(int port) {
-
         //表示服务器连接监听线程组,专门接受 accept 新的客户端client 连接
         EventLoopGroup bossLoopGroup = new NioEventLoopGroup();
         try {
@@ -40,7 +39,7 @@
             //7、监听通道关闭事件,应用程序会一直等待,直到channel关闭
             channelFuture.channel().closeFuture().sync();
         } catch (Exception e) {
-            log.error("error:"+e.getMessage());
+            log.error("error:" + e.getMessage());
         } finally {
             log.info("netty udp close!");
             //8 关闭EventLoopGroup,
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 50a9b71..2f6c991 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,11 +1,34 @@
 spring:
+  datasource:
+      #  使用druid数据库连接池
+    druid:
+        #开启druid监控web
+      stat-view-servlet:
+        enabled: true
+      driver-class-name: org.postgresql.Driver
+          #    url: jdbc:postgresql://111.40.46.199:15432/ry-vue?stringtype=unspecified
+          #    username: postgres
+          #    password: Yykj.2021
+      url: jdbc:postgresql://192.168.1.15:5432/ry-vue?stringtype=unspecified
+      username: postgres
+      password: postgres
+      #最大连接数
+      maxActive: 30
+      #最小连接数
+      minIdle: 5
+      #获取连接的最大等待时间
+      maxWait: 10000
+      #解决mysql8小时的问题
+      validation-query: SELECT 'X'
+      #空闲连接的检查时间间隔
+      timeBetweenEvictionRunsMillis: 60000
+      #空闲连接最小空闲时间
+      minEvictableIdleTimeMillis: 300000
   netty:
     udp:
       port: 40000
       enabled: true
     tcp:
-      host: 112.98.126.2
-      port: 1200
       enabled: true
   mqtt:
     host: tcp://192.168.1.15:1883
@@ -18,14 +41,6 @@
     enabled: true
   stealelec:
     url: http://iot.zhdk.net:8090/Warning/GetWarning?userName=cy4oil
-  datasource:
-    driver-class-name: org.postgresql.Driver
-#    url: jdbc:postgresql://111.40.46.199:15432/ry-vue?stringtype=unspecified
-#    username: postgres
-#    password: Yykj.2021
-    url: jdbc:postgresql://192.168.1.15:5432/ry-vue?stringtype=unspecified
-    username: postgres
-    password: postgres
 mybatis:
   typeAliasesPackage: com.ard.alarm.**.domain
   mapperLocations: classpath:/mapper/*.xml
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
index 390b765..02e95f2 100644
--- a/src/main/resources/logback-spring.xml
+++ b/src/main/resources/logback-spring.xml
@@ -76,13 +76,35 @@
             <onMismatch>DENY</onMismatch>
         </filter>
     </appender>
-    <!--雷达报警日志输出-->
-    <appender name="radar" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>${log.path}/radar.log</file>
+    <!--Netty日志输出-->
+    <appender name="netty" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/netty.log</file>
         <!--循环政策:基于时间创建日志文件-->
         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
             <!--日志文件名格式-->
-            <fileNamePattern>${log.path}/radar.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <fileNamePattern>${log.path}/netty.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!--日志最大的历史60天-->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!--过滤的级别-->
+            <level>INFO</level>
+            <!--匹配时的操作:接收(记录)-->
+            <onMatch>ACCEPT</onMatch>
+            <!--不匹配时的操作:拒绝(不记录)-->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+    <!--Mqtt日志输出-->
+    <appender name="mqtt" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/mqtt.log</file>
+        <!--循环政策:基于时间创建日志文件-->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件名格式-->
+            <fileNamePattern>${log.path}/mqtt.%d{yyyy-MM-dd}.log</fileNamePattern>
             <!--日志最大的历史60天-->
             <maxHistory>60</maxHistory>
         </rollingPolicy>
@@ -106,16 +128,20 @@
         <appender-ref ref="sys-info"/>
     </root>
     <!--管线泄露报警操作日志-->
-    <root level="INFO">
+    <logger name="tube" level="INFO">
         <appender-ref ref="tube"/>
-    </root>
+    </logger>
     <!--通用光电报警操作日志-->
-    <root level="INFO">
+    <logger name="camera" level="INFO">
         <appender-ref ref="camera"/>
-    </root>
-    <!--雷达报警日志-->
-    <root level="INFO">
-        <appender-ref ref="radar"/>
-    </root>
+    </logger>
+    <!--Netty日志-->
+    <logger name="netty"  level="INFO">
+        <appender-ref ref="netty"/>
+    </logger>
+    <!--Mqtt日志-->
+    <logger name="mqtt"  level="INFO">
+        <appender-ref ref="mqtt"/>
+    </logger>
 </configuration>
 

--
Gitblit v1.9.3