home 2 年之前
当前提交
28472865ad

+ 115 - 0
config

@@ -0,0 +1,115 @@
+{
+	"webSocketUrl": "ws://127.0.0.1:8300/webStock/webStockProgram",
+	"debug": 1,
+
+	"instructionsMap": {
+
+		"out1": [{
+			"ip": "192.168.5.16",
+			"port": 20058,
+			"agreement": 1
+		}],
+
+		"in1": [{
+			"ip": "192.168.5.11",
+			"port": 20058,
+			"agreement": 1
+		}],
+
+		"out4": [{
+			"ip": "192.168.5.42",
+			"port": 20058,
+			"agreement": 1
+		}],
+
+		"in4": [{
+			"ip": "192.168.5.41",
+			"port": 20058,
+			"agreement": 1
+		}],
+
+		"check1": [{
+				"ip": "192.168.5.12",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.13",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.14",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.17",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.18",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.19",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.37",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.36",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.35",
+				"port": 20058,
+				"agreement": 1
+			},
+			{
+				"ip": "192.168.5.34",
+				"port": 20058,
+				"agreement": 1
+			}
+		],
+
+		"check4": [{
+				"ip": "192.168.5.43",
+				"port": 20058,
+				"agreement": 2
+			},
+			{
+				"ip": "192.168.5.44",
+				"port": 20058,
+				"agreement": 2
+			},
+			{
+				"ip": "192.168.5.45",
+				"port": 20058,
+				"agreement": 2
+			},
+			{
+				"ip": "192.168.5.46",
+				"port": 20058,
+				"agreement": 2
+			},
+			{
+				"ip": "192.168.5.48",
+				"port": 20058,
+				"agreement": 2
+			},
+			{
+				"ip": "192.168.5.49",
+				"port": 20058,
+				"agreement": 2
+			}
+		]
+	}
+}

+ 95 - 0
pom.xml

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>js-rfid</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.java-websocket</groupId>
+            <artifactId>Java-WebSocket</artifactId>
+            <version>1.5.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.24</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.80</version>
+        </dependency>
+
+        <!-- TCP相关jar包加载项 begin (以下都属本地jar包,需要手动添加到本地maven资源库) -->
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>common</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>common-network</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>common-sdk</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>common-serialport</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>common-udp</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>jna</artifactId>
+            <version>1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fjhx.rfid-r2000</groupId>
+            <artifactId>RXTXcomm</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <!-- TCP相关jar包加载项 end -->
+
+
+    </dependencies>
+
+</project>

+ 86 - 0
src/main/java/com/fjhx/MyMain.java

@@ -0,0 +1,86 @@
+package com.fjhx;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.entity.Config;
+import com.fjhx.service.Service;
+import com.fjhx.service.impl.ServiceImpl;
+import com.fjhx.utils.BaseWebSocketClient;
+import com.fjhx.utils.MyUtil;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+
+
+public class MyMain {
+
+    public static BaseWebSocketClient client = null;
+    public static Config config;
+    public static Service service = new ServiceImpl();
+
+    public static void main(String[] args) throws IOException {
+
+        System.out.println("Version: 22-11-15-16-06");
+
+        MyUtil.infoLog("程序启动中...");
+
+        // 读取配置文件
+        if (!readConfigFile()) {
+            return;
+        }
+
+        // 开启webSocket连接
+        connectWebSocket();
+
+    }
+
+    /**
+     * 开启webSocket连接
+     */
+    public static void connectWebSocket() {
+
+        try {
+            client = BaseWebSocketClient.init(config.getWebSocketUrl());
+            client.connect();
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 读取配置文件
+     */
+    public static boolean readConfigFile() throws IOException {
+        // 获取配置文件路径
+        File file = new File(MyUtil.dir + "\\config");
+        if (!file.exists()) {
+            MyUtil.errorLog("配置文件不存在");
+            return false;
+        }
+
+        // 读取配置文件
+        InputStreamReader read = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
+        BufferedReader bufferedReader = new BufferedReader(read);
+        StringBuilder builder = new StringBuilder();
+        String lineTxt;
+        while ((lineTxt = bufferedReader.readLine()) != null) {
+            String trim = lineTxt.trim();
+            if (!trim.startsWith("#")) {
+                builder.append(trim);
+            }
+        }
+
+        String json = builder.toString();
+
+        try {
+            config = JSONObject.parseObject(json, Config.class);
+        } catch (Exception e) {
+            MyUtil.errorLog("配置文件格式错误");
+            return false;
+        }
+
+        return true;
+    }
+
+}

+ 30 - 0
src/main/java/com/fjhx/constant/UdpConstant.java

@@ -0,0 +1,30 @@
+package com.fjhx.constant;
+
+public interface UdpConstant {
+
+    /**
+     * rfid udp默认绑定端口
+     */
+    Integer DEFAULT_BINDING_PORT = 0;
+
+    /**
+     * rfid udp开始读取数据指令
+     */
+    String START_READ_INSTRUCTION = "A50401005501";
+
+    /**
+     * rfid udp停止读取数据指令
+     */
+    String STOP_READ_INSTRUCTION = "A504010060F6";
+
+    /**
+     * UDP返回数据截取RFID开始下标(从21开始)
+     */
+    Integer UDP_RESULT_DATA_SUBSTRING_RFID_BEGIN_INDEX = 20;
+
+    /**
+     * UDP返回数据截取RFID结束下标(从最后往前推10位)
+     */
+    Integer UDP_RESULT_DATA_SUBSTRING_RFID_END_INDEX = 10;
+
+}

+ 35 - 0
src/main/java/com/fjhx/constant/WebSocketConstant.java

@@ -0,0 +1,35 @@
+package com.fjhx.constant;
+
+public interface WebSocketConstant {
+
+    /**
+     * 上位机userId
+     */
+    String WEB_STOCK_PROGRAM = "webStockProgram";
+
+    /**
+     * 转发userId key
+     */
+    String FORWARD_USER_ID = "forwardUserId";
+
+    /**
+     * 转发session key
+     */
+    String FORWARD_SESSION_ID = "forwardSessionId";
+
+    /**
+     * 初始化返回
+     */
+    int ON_OPEN_TYPE = 1;
+
+    /**
+     * 操作上位机
+     */
+    int OPERATING_UPPER_COMPUTER = 2;
+
+    /**
+     * 推送rfid
+     */
+    int PUSH_RFID = 3;
+
+}

+ 26 - 0
src/main/java/com/fjhx/entity/Config.java

@@ -0,0 +1,26 @@
+package com.fjhx.entity;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class Config {
+
+    /**
+     * webSocket路径
+     */
+    private String webSocketUrl;
+
+    /**
+     * 调试模式
+     */
+    private Integer debug;
+
+    /**
+     * 指令集合
+     */
+    private Map<String, List<ConnectConfig>> instructionsMap;
+
+}

+ 23 - 0
src/main/java/com/fjhx/entity/ConnectConfig.java

@@ -0,0 +1,23 @@
+package com.fjhx.entity;
+
+import lombok.Data;
+
+@Data
+public class ConnectConfig {
+
+    /**
+     * ip
+     */
+    private String ip;
+
+    /**
+     * 端口号
+     */
+    private Integer port;
+
+    /**
+     * 协议 1:tcp 2:udp
+     */
+    private Integer agreement;
+
+}

+ 36 - 0
src/main/java/com/fjhx/entity/MessageEntity.java

@@ -0,0 +1,36 @@
+package com.fjhx.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class MessageEntity {
+
+    /**
+     * 用户id
+     */
+    private String userId;
+
+    /**
+     * 会话id
+     */
+    private String sessionId;
+
+    /**
+     * 消息创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 类型
+     */
+    private Integer type;
+
+    /**
+     * 消息主体
+     */
+    private JSONObject data;
+
+}

+ 377 - 0
src/main/java/com/fjhx/entity/test

@@ -0,0 +1,377 @@
+[
+  "B00000000000000000017866",
+  "A0000788DDD90140000A0149",
+  "B00000000000000000013527",
+  "A0003741DDD901400003015A",
+  "B00000000000000000013740",
+  "A0002990DDD90140000C014B",
+  "B00000000000000000017538",
+  "B00000000000000000017598",
+  "B00000000000000000020307",
+  "A0000086DDD90140000B01A2",
+  "B00000000000000000017591",
+  "A0003741DDD90140000301DD",
+  "A0000788DDD90140000A017D",
+  "B00000000000000000018042",
+  "A0002990DDD90140000C0180",
+  "B00000000000000000013600",
+  "B00000000000000000017596",
+  "B00000000000000000014242",
+  "B00000000000000000013098",
+  "B00000000000000000020201",
+  "A00000000000000000010C72",
+  "B00000000000000000013251",
+  "B00000000000000000003300",
+  "B00000000000000000013003",
+  "B00000000000000000017595",
+  "A0000788DDD90140000A0176",
+  "B00000000000000000018014",
+  "B00000000000000000017961",
+  "B00000000000000000015852",
+  "B00000000000000000014338",
+  "A0000086DDD90140000B017A",
+  "A0003741DDD9014000030004",
+  "A0003741DDD901400000019A",
+  "B00000000000000000013226",
+  "B00000000000000000003314",
+  "B00000000000000000014832",
+  "A0000086DDD90140000B002E",
+  "B00000000000000000025713",
+  "A0000788DDD90140000A014F",
+  "A0000086DDD90140000B0134",
+  "B00000000000000000018048",
+  "A0000086DDD90140000B002C",
+  "A0002990DDD90140000C012B",
+  "A0002990DDD90140000C017D",
+  "A0002990DDD90140000C0170",
+  "B00000000000000000018015",
+  "A0000086DDD90140000B0101",
+  "B00000000000000000013102",
+  "B00000000000000000018008",
+  "A0003741DDD901400003019C",
+  "B00000000000000000017937",
+  "A0003741DDD9014000030147",
+  "B00000000000000000018050",
+  "A0002990DDD90140000C018A",
+  "B00000000000000000029125",
+  "A0000086DDD90140000B0165",
+  "B00000000000000000014435",
+  "B00000000000000000010732",
+  "B00000000000000000013681",
+  "A0002990DDD90140000C013A",
+  "A0003741DDD9014000000160",
+  "300000000000000000A00136",
+  "B00000000000000000017935",
+  "A0000086DDD90140000B0133",
+  "A0003741DDD9014000030020",
+  "A0003741DDD90140000E0206",
+  "B00000000000000000013352",
+  "B00000000000000000013576",
+  "B00000000000000000018045",
+  "A0003741DDD9014000030134",
+  "A0000086DDD90140000B0176",
+  "B00000000000000000017982",
+  "B00000000000000000018016",
+  "A0003741DDD9014000030160",
+  "B00000000000000000017530",
+  "A0000086DDD90140000B0031",
+  "B00000000000000000018257",
+  "A0000086DDD90140000B002D",
+  "B00000000000000000018018",
+  "B00000000000000000025490",
+  "B00000000000000000012771",
+  "B00000000000000000027588",
+  "B00000000000000000013406",
+  "B00000000000000000003067",
+  "A0000086DDD90140000B001D",
+  "B00000000000000000017532",
+  "A0000788DDD90140000A014D",
+  "B00000000000000000014717",
+  "A0000086DDD90140000B00BD",
+  "B00000000000000000018021",
+  "B00000000000000000018009",
+  "A0000788DDD90140000A017C",
+  "B00000000000000000017698",
+  "B00000000000000000026605",
+  "A0003741DDD9014000030131",
+  "B00000000000000000013736",
+  "B00000000000000000017599",
+  "A0000788DDD90140000A017A",
+  "B00000000000000000017846",
+  "B00000000000000000026493",
+  "B00000000000000000018006",
+  "B00000000000000000017639",
+  "B00000000000000000017882",
+  "B00000000000000000017594",
+  "B00000000000000000026911",
+  "B00000000000000000017971",
+  "A0000086DDD90140000B001E",
+  "A0002990DDD90140000C0191",
+  "B00000000000000000017963",
+  "B00000000000000000017938",
+  "B00000000000000000026599",
+  "B00000000000000000017535",
+  "B00000000000000000014673",
+  "A0003741DDD90140000301C1",
+  "B00000000000000000017970",
+  "A0000788DDD90140000A0179",
+  "B00000000000000000018020",
+  "A0003741DDD90140000301EC",
+  "A0003741DDD901400003000F",
+  "B00000000000000000017597",
+  "A0000086DDD90140000B00FD",
+  "A0002990DDD90140000C024B",
+  "A0002990DDD90140000C01A5",
+  "B00000000000000000013058",
+  "A0002990DDD90140000C0145",
+  "B00000000000000000012949",
+  "A0000788DDD90140000A00CB",
+  "A0002990DDD90140000C0147",
+  "B00000000000000000017593",
+  "A0000788DDD90140000A0178",
+  "B00000000000000000020153",
+  "A0000086DDD90140000B0131",
+  "A0000086DDD90140000B0196",
+  "A0002990DDD90140000C0125",
+  "A0003741DDD9014000000174",
+  "B00000000000000000020383",
+  "A0003741DDD9014000030155",
+  "A0000086DDD90140000B0127",
+  "300000000000000000A001DC",
+  "B00000000000000000017865",
+  "A0003741DDD901400003015D",
+  "A0002990DDD90140000C0194",
+  "B00000000000000000027591",
+  "A0002990DDD90140000C015A",
+  "B00000000000000000012701",
+  "A0000788DDD90140000A016B",
+  "A0000788DDD90140000A016D",
+  "B00000000000000000012801",
+  "B00000000000000000002657",
+  "B00000000000000000025491",
+  "A0003741DDD90140000301F4",
+  "A0002990DDD90140000C00F6",
+  "A0000086DDD90140000B0139",
+  "A0002990DDD90140000C0234",
+  "B00000000000000000013244",
+  "B00000000000000000018007",
+  "A0000086DDD90140000B0195",
+  "A0000788DDD90140000A0170",
+  "A0000086DDD90140000B0017",
+  "B00000000000000000018026",
+  "B00000000000000000017537",
+  "B00000000000000000012755",
+  "B00000000000000000017854",
+  "B00000000000000000025689",
+  "B00000000000000000017966",
+  "A0000788DDD90140000A0144",
+  "B00000000000000000013627",
+  "B00000000000000000018707",
+  "A0000086DDD90140000B0125",
+  "A0002990DDD90140000C00FD",
+  "A0000086DDD90140000B012C",
+  "A0000086DDD90140000B00C1",
+  "A0003741DDD90140000301C4",
+  "A0000788DDD90140000A0172",
+  "B00000000000000000003308",
+  "A0003741DDD90140000301DC",
+  "A0003741DDD9014000030153",
+  "A0002990DDD90140000C019B",
+  "A0003741DDD901400003001F",
+  "A0002990DDD90140000C01AF",
+  "B00000000000000000013599",
+  "A00000000000000000010C85",
+  "B00000000000000000017531",
+  "B00000000000000000012984",
+  "A0002990DDD90140000C0153",
+  "B00000000000000000017590",
+  "A0003741DDD90140000E004C",
+  "B00000000000000000010005",
+  "B00000000000000000018047",
+  "A0000788DDD90140000A0175",
+  "B00000000000000000018709",
+  "A0000086DDD90140000B003C",
+  "B00000000000000000017976",
+  "A0002990DDD90140000C015E",
+  "B00000000000000000028854",
+  "A0002990DDD90140000C00EB",
+  "A0002990DDD90140000C017E",
+  "B00000000000000000026581",
+  "B00000000000000000018004",
+  "B00000000000000000017885",
+  "A0003741DDD9014000030202",
+  "B00000000000000000026184",
+  "A0003741DDD9014000000187",
+  "A0000086DDD90140000B0130",
+  "B00000000000000000014193",
+  "A0000086DDD90140000B005C",
+  "A0002990DDD90140000C00F4",
+  "B00000000000000000017533",
+  "A0000086DDD90140000B017D",
+  "A0002990DDD90140000C0189",
+  "B00000000000000000013490",
+  "B00000000000000000017769",
+  "B00000000000000000020341",
+  "B00000000000000000018022",
+  "A0000788DDD90140000A0143",
+  "B00000000000000000025236",
+  "A0003741DDD9014000030209",
+  "A0003741DDD901400003011F",
+  "A0000788DDD90140000A014E",
+  "B00000000000000000017883",
+  "B00000000000000000012788",
+  "300000000000000000A0012B",
+  "300000000000000000A000AD",
+  "A0000086DDD90140000B0136",
+  "300000000000000000A0000C",
+  "B00000000000000000018024",
+  "B00000000000000000018090",
+  "A0000086DDD90140000B00FE",
+  "A0000086DDD90140000B013D",
+  "B00000000000000000012781",
+  "A0003741DDD90140000300E7",
+  "B00000000000000000012809",
+  "B00000000000000000013097",
+  "A0002990DDD90140000C0255",
+  "B00000000000000000003324",
+  "A0003741DDD901400003019F",
+  "A0000086DDD90140000B0138",
+  "A0002990DDD90140000C018E",
+  "B00000000000000000012786",
+  "A0000788DDD90140000A0171",
+  "A0003741DDD90140000300A2",
+  "B00000000000000000017853",
+  "B00000000000000000028319",
+  "A0003741DDD901400003019D",
+  "A0000788DDD90140000A018D",
+  "B00000000000000000025515",
+  "A0000788DDD90140000A0187",
+  "A0000788DDD90140000A013E",
+  "B00000000000000000012756",
+  "B00000000000000000007958",
+  "B00000000000000000013463",
+  "A0003741DDD901400000017A",
+  "B00000000000000000018023",
+  "B00000000000000000014184",
+  "B00000000000000000026644",
+  "B00000000000000000014318",
+  "A0003741DDD9014000030154",
+  "A0002990DDD90140000C01AD",
+  "A0000086DDD90140000B0025",
+  "B00000000000000000013445",
+  "A0000086DDD90140000B012D",
+  "A0003741DDD9014000030188",
+  "B00000000000000000025598",
+  "B00000000000000000018695",
+  "A0002990DDD90140000C0169",
+  "B00000000000000000017965",
+  "A0002990DDD90140000C0151",
+  "B00000000000000000014129",
+  "B00000000000000000017930",
+  "B00000000000000000020516",
+  "A0002990DDD90140000C0235",
+  "A0000086DDD90140000B002B",
+  "A0000086DDD90140000B0179",
+  "B00000000000000000013329",
+  "A0000788DDD90140000A0142",
+  "A0000086DDD90140000B00DE",
+  "A0002990DDD90140000C0188",
+  "B00000000000000000017638",
+  "A0003741DDD90140000001C5",
+  "A0002990DDD90140000C0146",
+  "B00000000000000000018017",
+  "B00000000000000000013115",
+  "B00000000000000000018003",
+  "A0002990DDD90140000C017C",
+  "B00000000000000000014835",
+  "B00000000000000000017931",
+  "B00000000000000000013464",
+  "B00000000000000000017884",
+  "A0003741DDD9014000030158",
+  "B00000000000000000019723",
+  "A0003741DDD901400003020A",
+  "300000000000000000A00100",
+  "A0002990DDD90140000C016C",
+  "A0003741DDD901400003014B",
+  "A0000086DDD90140000B0032",
+  "B00000000000000000017979",
+  "B00000000000000000018019",
+  "B00000000000000000002800",
+  "B00000000000000000014448",
+  "A0000086DDD90140000B012E",
+  "A0000788DDD90140000A0140",
+  "B00000000000000000013087",
+  "B00000000000000000010019",
+  "A0003741DDD90140000300E6",
+  "B00000000000000000013410",
+  "A0003741DDD901400003014F",
+  "B00000000000000000003053",
+  "300000000000000000A00101",
+  "A0000788DDD90140000A0145",
+  "A0002990DDD90140000C0127",
+  "B00000000000000000018049",
+  "B00000000000000000014260",
+  "B00000000000000000014124",
+  "B00000000000000000020439",
+  "B00000000000000000018010",
+  "A00000000000000000010ABC",
+  "B00000000000000000017847",
+  "B00000000000000000017624",
+  "A0000086DDD90140000B012A",
+  "B00000000000000000017650",
+  "B00000000000000000018046",
+  "A0000788DDD90140000A00D6",
+  "B00000000000000000013096",
+  "A0000788DDD90140000A016F",
+  "B00000000000000000003273",
+  "B00000000000000000027537",
+  "A0000086DDD90140000B0132",
+  "A0003741DDD9014000030198",
+  "A0000788DDD90140000A016C",
+  "A0000086DDD90140000B001B",
+  "A0003741DDD90140000E00C0",
+  "A0000086DDD90140000B001C",
+  "B00000000000000000013233",
+  "A0003741DDD90140000300DF",
+  "B00000000000000000018025",
+  "300000000000000000A000EC",
+  "A0002990DDD90140000C012F",
+  "B00000000000000000014141",
+  "A0000086DDD90140000B0024",
+  "B00000000000000000013351",
+  "A0000086DDD90140000B0150",
+  "B00000000000000000013620",
+  "B00000000000000000020435",
+  "A0000788DDD90140000A0173",
+  "B00000000000000000018013",
+  "B00000000000000000003323",
+  "B00000000000000000019207",
+  "B00000000000000000013749",
+  "B00000000000000000028678",
+  "B00000000000000000027538",
+  "A0000788DDD90140000A0169",
+  "B00000000000000000012824",
+  "B00000000000000000002159",
+  "A0002990DDD90140000C0172",
+  "A0002990DDD90140000C0184",
+  "A0002990DDD90140000C0168",
+  "B00000000000000000012798",
+  "B00000000000000000007873",
+  "B00000000000000000017534",
+  "A0002990DDD90140000C0124",
+  "A0000788DDD90140000A017B",
+  "A0003741DDD9014000000323",
+  "B00000000000000000025612",
+  "A0000788DDD90140000A018F",
+  "A0002990DDD90140000C01A4",
+  "B00000000000000000025514",
+  "A0003741DDD9014000010116",
+  "A0000788DDD90140000A0141",
+  "B00000000000000000013334",
+  "A0002990DDD90140000C0115",
+  "A0003741DDD90140000E0037",
+  "B00000000000000000018044",
+  "B00000000000000000018005",
+  "B00000000000000000012749",
+  "A0003741DDD90140000E0220"
+]

+ 50 - 0
src/main/java/com/fjhx/enums/AgreementEnum.java

@@ -0,0 +1,50 @@
+package com.fjhx.enums;
+
+import com.fjhx.service.Operation;
+import com.fjhx.service.impl.TcpOperation;
+import com.fjhx.service.impl.UdpOperation;
+import lombok.Getter;
+
+import java.util.HashMap;
+
+/**
+ * 入库类型
+ */
+@Getter
+public enum AgreementEnum {
+
+    TCP(1),
+    UDP(2);
+
+    private final Integer type;
+
+    private static final HashMap<Integer, AgreementEnum> map = new HashMap<>();
+
+    AgreementEnum(Integer type) {
+        this.type = type;
+    }
+
+    static {
+        for (AgreementEnum value : AgreementEnum.values()) {
+            map.put(value.getType(), value);
+        }
+    }
+
+    public Operation getOperation() {
+        switch (this) {
+            case TCP:
+                return new TcpOperation();
+            case UDP:
+                return new UdpOperation();
+        }
+        return null;
+    }
+
+    /**
+     * 根据type获取枚举
+     */
+    public static AgreementEnum get(Integer type) {
+        return map.get(type);
+    }
+
+}

+ 57 - 0
src/main/java/com/fjhx/enums/MessageTypeEnum.java

@@ -0,0 +1,57 @@
+package com.fjhx.enums;
+
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * 入库类型
+ */
+@Getter
+public enum MessageTypeEnum {
+
+    READ(1, "启动读写器并返回所有数据"),
+    DISTINCT_READ(2, "启动读写器并返回去重数据"),
+    SEND_RFID(3, "推送rfid"),
+    CLOSE(9, "关闭读写器");
+
+    private final Integer type;
+    private final String name;
+
+    private static final HashMap<Integer, MessageTypeEnum> map = new HashMap<>();
+    private static final List<Integer> list = new ArrayList<>();
+
+    MessageTypeEnum(Integer type, String name) {
+        this.type = type;
+        this.name = name;
+    }
+
+    static {
+        for (MessageTypeEnum value : MessageTypeEnum.values()) {
+            map.put(value.getType(), value);
+            list.add(value.getType());
+        }
+    }
+
+    /**
+     * 根据type获取枚举
+     */
+    public static MessageTypeEnum get(Integer type) {
+        return map.get(type);
+    }
+
+    /**
+     * 根据type值获取枚举
+     */
+    public static String getName(Integer type) {
+        return map.get(type).getName();
+    }
+
+    public static List<Integer> list() {
+        return list;
+    }
+
+
+}

+ 51 - 0
src/main/java/com/fjhx/service/Operation.java

@@ -0,0 +1,51 @@
+package com.fjhx.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.MyMain;
+import com.fjhx.constant.WebSocketConstant;
+import com.fjhx.entity.ConnectConfig;
+import com.fjhx.entity.MessageEntity;
+import com.fjhx.utils.MyUtil;
+
+import java.util.Date;
+import java.util.List;
+
+public interface Operation {
+
+    /**
+     * 开启扫描rfid,并推送去重数据
+     *
+     * @param userId            用户id
+     * @param sessionId         会话id
+     * @param connectConfigList ip配置列表
+     */
+    void distinctRead(String userId, String sessionId, List<ConnectConfig> connectConfigList, JSONObject data);
+
+    /**
+     * 关闭扫描
+     */
+    void close();
+
+    /**
+     * 发送rfid数据
+     *
+     * @param rfid rfid
+     */
+    default void sendRfidDate(String userId, String sessionId, String rfid, JSONObject data) {
+        MessageEntity messageEntity = new MessageEntity();
+
+        messageEntity.setUserId(userId);
+        messageEntity.setSessionId(sessionId);
+        messageEntity.setCreateTime(new Date());
+        messageEntity.setType(WebSocketConstant.PUSH_RFID);
+
+        data.put("rfid", rfid);
+        messageEntity.setData(data);
+
+        String jsonString = JSONObject.toJSONString(messageEntity);
+        MyMain.client.send(jsonString);
+
+        MyUtil.infoLog(jsonString);
+    }
+
+}

+ 9 - 0
src/main/java/com/fjhx/service/Service.java

@@ -0,0 +1,9 @@
+package com.fjhx.service;
+
+import com.fjhx.entity.MessageEntity;
+
+public interface Service {
+
+    void handleMessage(MessageEntity messageEntity);
+
+}

+ 118 - 0
src/main/java/com/fjhx/service/impl/ServiceImpl.java

@@ -0,0 +1,118 @@
+package com.fjhx.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.MyMain;
+import com.fjhx.constant.WebSocketConstant;
+import com.fjhx.entity.ConnectConfig;
+import com.fjhx.entity.MessageEntity;
+import com.fjhx.enums.AgreementEnum;
+import com.fjhx.enums.MessageTypeEnum;
+import com.fjhx.service.Operation;
+import com.fjhx.service.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+public class ServiceImpl implements Service {
+
+    public static final Map<String, List<Operation>> operationMap = new ConcurrentHashMap<>();
+
+    @Override
+    public void handleMessage(MessageEntity messageEntity) {
+
+        if (WebSocketConstant.OPERATING_UPPER_COMPUTER != messageEntity.getType()) {
+            return;
+        }
+
+        // 数据
+        JSONObject data = messageEntity.getData();
+        String forwardUserId = ObjectUtil.defaultIfNull(data.getString(WebSocketConstant.FORWARD_USER_ID), "default");
+        String forwardSessionId = ObjectUtil.defaultIfNull(data.getString(WebSocketConstant.FORWARD_SESSION_ID), "default");
+
+        // 操作上位机类型
+        Integer type = data.getInteger("type");
+
+        switch (MessageTypeEnum.get(type)) {
+            // case READ:
+            //     read(sessionId, connectConfigList);
+            //     break;
+            case DISTINCT_READ:
+                // 获取指令
+                String instructions = data.getString("instructions");
+                // ip配置集合
+                List<ConnectConfig> connectConfigList = MyMain.config.getInstructionsMap().get(instructions);
+                distinctRead(forwardUserId, forwardSessionId, connectConfigList, data);
+                break;
+            case CLOSE:
+                close(forwardSessionId);
+                break;
+        }
+
+    }
+
+    /**
+     * 读取数据
+     *
+     * @param userId            用户id
+     * @param sessionId         会话id
+     * @param connectConfigList 连接配置
+     */
+    private void distinctRead(String userId, String sessionId, List<ConnectConfig> connectConfigList, JSONObject data) {
+        List<Operation> operationList = newOperationList(sessionId);
+
+        for (AgreementEnum agreementEnum : AgreementEnum.values()) {
+            List<ConnectConfig> itemConnectConfigList = getConnectConfigList(agreementEnum, connectConfigList);
+            if (itemConnectConfigList.size() > 0) {
+                Operation operation = agreementEnum.getOperation();
+                assert operation != null;
+                operation.distinctRead(userId, sessionId, itemConnectConfigList, data);
+                operationList.add(operation);
+            }
+        }
+
+        if (operationList.size() == 0) {
+            operationMap.remove(sessionId);
+        }
+    }
+
+    /**
+     * 关闭读取
+     *
+     * @param sessionId 会话id
+     */
+    private void close(String sessionId) {
+        List<Operation> operationList = operationMap.get(sessionId);
+        if (operationList != null) {
+            operationList.forEach(Operation::close);
+            operationMap.remove(sessionId);
+        }
+    }
+
+    /**
+     * 获取配置集合
+     */
+    private List<ConnectConfig> getConnectConfigList(AgreementEnum agreementEnum, List<ConnectConfig> connectConfigList) {
+        return connectConfigList.stream()
+                .filter(item -> agreementEnum.equals(AgreementEnum.get(item.getAgreement())))
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 获取本次会话id的操作集合
+     */
+    private List<Operation> newOperationList(String sessionId) {
+        List<Operation> operationList = operationMap.computeIfAbsent(sessionId, k -> new ArrayList<>());
+
+        if (operationList.size() > 0) {
+            operationList.forEach(Operation::close);
+            operationList.clear();
+        }
+
+        return operationList;
+    }
+
+}

+ 84 - 0
src/main/java/com/fjhx/service/impl/TcpOperation.java

@@ -0,0 +1,84 @@
+package com.fjhx.service.impl;
+
+import cn.hutool.core.collection.ConcurrentHashSet;
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.entity.ConnectConfig;
+import com.fjhx.service.Operation;
+import com.fjhx.utils.ThreadPoolManager;
+import com.rfid.callBack.CallBack;
+import com.rfid.uhf.controller.impl.ReaderR2000;
+import com.rfid.uhf.service.ReaderR2000Service;
+import com.rfid.uhf.service.impl.ReaderR2000ServiceImpl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class TcpOperation implements Operation {
+
+    private final ReaderR2000Service service = new ReaderR2000ServiceImpl();
+    private final List<ReaderR2000> readerR2000List = new ArrayList<>();
+    private final Set<String> rfidSet = new ConcurrentHashSet<>();
+
+    @Override
+    public void distinctRead(String userId, String sessionId, List<ConnectConfig> connectConfigList, JSONObject data) {
+
+        for (ConnectConfig connectConfig : connectConfigList) {
+            ThreadPoolManager.execute(() -> {
+
+                ReaderR2000 reader = service.connect(
+                        connectConfig.getIp(),
+                        connectConfig.getPort(),
+                        getCallBack(userId, sessionId, data)
+                );
+
+                service.beginInvV2(reader);
+                readerR2000List.add(reader);
+
+            });
+        }
+
+    }
+
+    @Override
+    public void close() {
+        for (ReaderR2000 readerR2000 : readerR2000List) {
+            // 结束扫描
+            service.stopInvV2(readerR2000);
+            // 关闭连接
+            service.disconnect(readerR2000);
+        }
+    }
+
+    private CallBack.R2000 getCallBack(String userId, String sessionId, JSONObject data) {
+        return new CallBack.R2000() {
+
+            @Override
+            public void readData(String rfid, String rssi, String antennaNo, String deviceNo, String direction, String communicationMode) {
+                if (rfidSet.contains(rfid)) {
+                    return;
+                }
+                rfidSet.add(rfid);
+                sendRfidDate(userId, sessionId, rfid, data);
+            }
+
+            public void serialPortException(String name, boolean result) {
+
+            }
+
+            public void heartBeat(String value, String deviceNo, String communicationMode) {
+                // System.out.println("value " + value + " deviceNo " + deviceNo + " communicationMode " + communicationMode);
+            }
+
+            public void infraredTrigger(boolean direction, String value, String deviceNo, String communicationMode) {
+                // System.out.println("方向 " + direction + " 红外值 " + value + " 设备号 " + deviceNo + " IP或串口号 " + communicationMode);
+            }
+
+            public void onceReadTagEnd(boolean arg0) {
+
+            }
+
+        };
+    }
+
+}

+ 119 - 0
src/main/java/com/fjhx/service/impl/UdpOperation.java

@@ -0,0 +1,119 @@
+package com.fjhx.service.impl;
+
+import cn.hutool.core.collection.ConcurrentHashSet;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.constant.UdpConstant;
+import com.fjhx.entity.ConnectConfig;
+import com.fjhx.service.Operation;
+import com.fjhx.utils.ThreadPoolManager;
+import com.fjhx.utils.Utility;
+import lombok.SneakyThrows;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class UdpOperation implements Operation {
+
+    /**
+     * rfid集合
+     */
+    private final Set<String> rfidSet = new ConcurrentHashSet<>();
+
+    /**
+     * 设备连接配置
+     */
+    private List<ConnectConfig> connectConfigList = new ArrayList<>();
+
+    /**
+     * 监听开启状态标记
+     */
+    private boolean monitorFlag = true;
+
+
+    @SneakyThrows
+    @Override
+    public void distinctRead(String userId, String sessionId, List<ConnectConfig> connectConfigList, JSONObject data) {
+        this.connectConfigList = connectConfigList;
+
+        for (ConnectConfig connectConfig : connectConfigList) {
+            ThreadPoolManager.execute(() -> {
+
+                // 开启设备读取rfid
+                DatagramSocket datagramSocket = send(UdpConstant.START_READ_INSTRUCTION, connectConfig);
+                startMonitor(datagramSocket, userId, sessionId, data);
+
+            });
+        }
+
+    }
+
+    private void startMonitor(DatagramSocket datagramSocket, String userId, String sessionId, JSONObject data) {
+
+        new Thread(() -> {
+
+            while (monitorFlag) {
+                byte[] buf = new byte[128];
+                DatagramPacket packet = new DatagramPacket(buf, buf.length);
+                try {
+                    datagramSocket.receive(packet);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    break;
+                }
+
+                byte[] bytes = new byte[packet.getLength()];
+                System.arraycopy(buf, 0, bytes, 0, packet.getLength());
+                String str = Utility.bytes2HexString(bytes);
+
+                // 截取rfid
+                if (ObjectUtil.isEmpty(str) || str.length() < 20) {
+                    continue;
+                }
+
+                String rfid = str.substring(
+                        UdpConstant.UDP_RESULT_DATA_SUBSTRING_RFID_BEGIN_INDEX,
+                        str.length() - UdpConstant.UDP_RESULT_DATA_SUBSTRING_RFID_END_INDEX);
+
+                if (rfidSet.contains(rfid)) {
+                    return;
+                }
+                rfidSet.add(rfid);
+                sendRfidDate(userId, sessionId, rfid, data);
+            }
+
+        }).start();
+
+    }
+
+    @SneakyThrows
+    @Override
+    public void close() {
+
+        for (ConnectConfig connectConfig : connectConfigList) {
+            // 关闭设备读取rfid
+            send(UdpConstant.STOP_READ_INSTRUCTION, connectConfig);
+        }
+
+        monitorFlag = false;
+    }
+
+
+    @SneakyThrows
+    private DatagramSocket send(String instruction, ConnectConfig connectConfig) {
+        byte[] convert2HexArray = Utility.convert2HexArray(instruction);
+        DatagramPacket packets = new DatagramPacket(convert2HexArray, convert2HexArray.length,
+                InetAddress.getByName(connectConfig.getIp()), connectConfig.getPort());
+
+        DatagramSocket socket = new DatagramSocket(UdpConstant.DEFAULT_BINDING_PORT);
+        socket.send(packets);
+
+        return socket;
+    }
+
+}

+ 50 - 0
src/main/java/com/fjhx/utils/BaseWebSocketClient.java

@@ -0,0 +1,50 @@
+package com.fjhx.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fjhx.MyMain;
+import com.fjhx.entity.MessageEntity;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class BaseWebSocketClient extends WebSocketClient {
+
+    public BaseWebSocketClient(URI serverUri) {
+        super(serverUri);
+    }
+
+    @Override
+    public void onOpen(ServerHandshake serverHandshake) {
+        MyUtil.infoLog("连接成功...");
+    }
+
+    @Override
+    public void onMessage(String str) {
+        MyUtil.infoLog(str);
+        MessageEntity messageEntity = JSONObject.parseObject(str, MessageEntity.class);
+        MyMain.service.handleMessage(messageEntity);
+    }
+
+    @Override
+    public void onClose(int i, String s, boolean b) {
+        MyUtil.errorLog("连接断开...");
+        MyUtil.sleep(5 * 1000);
+        MyUtil.infoLog("尝试重连...");
+        MyMain.connectWebSocket();
+    }
+
+    @Override
+    public void onError(Exception e) {
+
+    }
+
+    /**
+     * 获取webSocketClient
+     */
+    public static BaseWebSocketClient init(String url) throws URISyntaxException {
+        return new BaseWebSocketClient(new URI(url));
+    }
+
+}

+ 84 - 0
src/main/java/com/fjhx/utils/MyUtil.java

@@ -0,0 +1,84 @@
+package com.fjhx.utils;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fjhx.MyMain;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Date;
+
+public class MyUtil {
+
+    // 程序存放地址
+    public static final String dir = System.getProperty("user.dir");
+
+    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
+    private static final String TIME_FORMAT = "HH:mm:ss.SSS";
+    private static final String DATE_FORMAT = "yyyy-MM-dd";
+
+    public static void sleep(long l) {
+        try {
+            Thread.sleep(l);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * info级别日志
+     */
+    public static void infoLog(String jsonStr) {
+        write(jsonStr, "log\\info");
+    }
+
+    /**
+     * error级别日志
+     */
+    public static void errorLog(String jsonStr) {
+        write(jsonStr, "log\\error");
+    }
+
+    /**
+     * 写入本地数据
+     *
+     * @param text     写入数据
+     * @param pathName 写入路径
+     */
+    private static void write(String text, String pathName) {
+        String path = dir + "\\" + pathName;
+        File file = new File(path);
+        if (!file.exists()) {
+            boolean mkdirs = file.mkdirs();
+            if (!mkdirs) {
+                System.out.println("文件夹创建失败");
+                return;
+            }
+        }
+
+        Date date = new Date();
+        OutputStreamWriter osw = null;
+        FileOutputStream fos = null;
+        try {
+            String filePath = path + "\\" + DateUtil.format(date, DATE_FORMAT) + ".log";
+            fos = new FileOutputStream(filePath, true);
+            osw = new OutputStreamWriter(fos);
+
+            text = " =====》 " + text;
+            System.out.println(DateUtil.format(date, DATE_TIME_FORMAT) + text);
+
+            if (MyMain.config == null || ObjectUtil.equals(MyMain.config.getDebug(), 1)) {
+                osw.write(DateUtil.format(date, TIME_FORMAT) + text + "\r\n");
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            IoUtil.close(osw);
+            IoUtil.close(fos);
+        }
+    }
+
+}

+ 69 - 0
src/main/java/com/fjhx/utils/ThreadPoolManager.java

@@ -0,0 +1,69 @@
+package com.fjhx.utils;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 线程池
+ */
+public class ThreadPoolManager {
+
+    //通过ThreadPoolExecutor的代理类来对线程池的管理
+    private static ThreadPollProxy mThreadPollProxy;
+
+    //单列对象
+    private static ThreadPollProxy getThreadPollProxy() {
+        synchronized (ThreadPollProxy.class) {
+            if (mThreadPollProxy == null) {
+                mThreadPollProxy = new ThreadPollProxy(10, 20, 1000);
+            }
+        }
+        return mThreadPollProxy;
+    }
+
+    /**
+     * 提交线程
+     *
+     * @param r
+     */
+    public static void execute(Runnable r) {
+        getThreadPollProxy().execute(r);
+    }
+
+    //通过ThreadPoolExecutor的代理类来对线程池的管理
+    private static class ThreadPollProxy {
+        private ThreadPoolExecutor poolExecutor;//线程池执行者 ,java内部通过该api实现对线程池管理
+        private final int corePoolSize;
+        private final int maximumPoolSize;
+        private final long keepAliveTime;
+
+        public ThreadPollProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
+            this.corePoolSize = corePoolSize;
+            this.maximumPoolSize = maximumPoolSize;
+            this.keepAliveTime = keepAliveTime;
+        }
+
+        //对外提供一个执行任务的方法
+        public void execute(Runnable r) {
+            if (poolExecutor == null || poolExecutor.isShutdown()) {
+                poolExecutor = new ThreadPoolExecutor(
+                        //核心线程数量
+                        corePoolSize,
+                        //最大线程数量
+                        maximumPoolSize,
+                        //当线程空闲时,保持活跃的时间
+                        keepAliveTime,
+                        //时间单元 ,毫秒级
+                        TimeUnit.MILLISECONDS,
+                        //线程任务队列
+                        new LinkedBlockingQueue<Runnable>(),
+                        //创建线程的工厂
+                        Executors.defaultThreadFactory());
+            }
+            poolExecutor.execute(r);
+        }
+    }
+
+}

+ 160 - 0
src/main/java/com/fjhx/utils/Utility.java

@@ -0,0 +1,160 @@
+package com.fjhx.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * 字符串,字节数据之间转换的帮助类
+ */
+public class Utility {
+    private static final Logger LOG = Logger.getLogger(Utility.class.getName());
+
+    public static String timeFormatString = "yyyy/MM/dd HH:mm:ss";
+    public static SimpleDateFormat timeFormat = new SimpleDateFormat(timeFormatString);
+
+    public static String hex(byte[] bytes) {
+        StringBuilder result = new StringBuilder();
+        for (byte aByte : bytes) {
+            int decimal = (int) aByte & 0xff;               // bytes widen to int, need mask, prevent sign extension
+            // get last 8 bits
+            String hex = Integer.toHexString(decimal);
+            if (hex.length() % 2 == 1) {                    // if half hex, pad with zero, e.g \t
+                hex = "0" + hex;
+            }
+            result.append(hex);
+        }
+        return result.toString();
+    }
+
+    /**
+     * 字符串转化成为16进制字符串
+     *
+     * @param s
+     * @return
+     */
+    public static String strTo16(String s) {
+        String str = "";
+        for (int i = 0; i < s.length(); i++) {
+            int ch = (int) s.charAt(i);
+            String s4 = Integer.toHexString(ch);
+            str = str + s4;
+        }
+        return str;
+    }
+
+    /**
+     * 字符串转换成为16进制(无需Unicode编码)
+     *
+     * @param str
+     * @return
+     */
+    public static String str2HexStr(String str) {
+        char[] chars = "0123456789ABCDEF".toCharArray();
+        StringBuilder sb = new StringBuilder("");
+        byte[] bs = str.getBytes();
+        int bit;
+        for (int i = 0; i < bs.length; i++) {
+            bit = (bs[i] & 0x0f0) >> 4;
+            sb.append(chars[bit]);
+            bit = bs[i] & 0x0f;
+            sb.append(chars[bit]);
+            // sb.append(' ');
+        }
+        return sb.toString().trim();
+    }
+
+    /**
+     * @param hexString
+     * @return
+     */
+    public static byte[] convert2HexArray(String hexString) {
+        int m = 0, n = 0;
+        int byteLen = hexString.length() / 2; // 每两个字符描述一个字节
+        byte[] ret = new byte[byteLen];
+        for (int i = 0; i < byteLen; i++) {
+            m = i * 2 + 1;
+            n = m + 1;
+            int intVal = Integer.decode("0x" + hexString.substring(i * 2, m) + hexString.substring(m, n));
+            ret[i] = (byte) intVal;
+        }
+        return ret;
+    }
+
+    /**
+     * @param b
+     * @param count convert number
+     * @return
+     */
+    public static String bytes2HexString(byte[] b, int count) {
+        StringBuilder ret = new StringBuilder();
+        for (int i = 0; i < count; i++) {
+            String hex = Integer.toHexString(b[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            ret.append(hex.toUpperCase());
+        }
+        return ret.toString();
+    }
+
+    public static String bytes2HexString(byte[] b) {
+        StringBuilder ret = new StringBuilder();
+        for (byte value : b) {
+            String hex = Integer.toHexString(value & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            ret.append(hex.toUpperCase());
+        }
+        return ret.toString();
+    }
+
+    public static byte BYTE(int i) {
+        return (byte) i;
+    }
+
+    /**
+     * check whether the str is a hex str
+     *
+     * @param str  str
+     * @param bits bits
+     * @return true or false
+     */
+    public static boolean isHexString(String str, int bits) {
+        String patten = "[abcdefABCDEF0123456789]{" + bits + "}";
+        if (str.matches(patten)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static boolean isHexString(String str) {
+        String patten = "[abcdefABCDEF0123456789]{1,}";
+        if (str.matches(patten)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static boolean isNumber(String str) {
+        String patten = "[-]{0,1}[0123456789]{0,}";
+        return str.matches(patten);
+    }
+
+    public static boolean isValiadTimeString(String dateString) {
+        timeFormat.setLenient(false);
+        try {
+            timeFormat.parse(dateString);
+        } catch (Exception ex) {
+            Logger.getLogger(Utility.class.getName()).log(Level.SEVERE, null, ex);
+            LOG.info(dateString + " bad format");
+            return false;
+        }
+        LOG.info(dateString);
+        return true;
+    }
+
+}

+ 7 - 0
src/main/resources/META-INF/MANIFEST.MF

@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Main-Class: com.fjhx.MyMain
+Class-Path: common-udp-1.0.jar common-sdk-1.0.jar lombok-1.18.24.jar com
+ mon-network-1.0.jar jna-1.0.jar fastjson-1.2.80.jar Java-WebSocket-1.5.
+ 3.jar RXTXcomm-1.0.jar common-1.0.jar slf4j-simple-1.7.25.jar hutool-al
+ l-5.8.8.jar slf4j-api-1.7.25.jar common-serialport-1.0.jar
+