From 3fef108b925349b467f0639aede38e0a918a2a7f Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期日, 13 七月 2025 22:00:33 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/thread/fake/FakeNyShuttleThread.java |  410 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 330 insertions(+), 80 deletions(-)

diff --git a/src/main/java/com/zy/core/thread/fake/FakeNyShuttleThread.java b/src/main/java/com/zy/core/thread/fake/FakeNyShuttleThread.java
index ab8594b..8362d60 100644
--- a/src/main/java/com/zy/core/thread/fake/FakeNyShuttleThread.java
+++ b/src/main/java/com/zy/core/thread/fake/FakeNyShuttleThread.java
@@ -2,8 +2,8 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.zy.common.Cools;
 import com.zy.common.SpringUtils;
-import com.zy.common.exception.CoolException;
 import com.zy.common.utils.RedisUtil;
 import com.zy.core.News;
 import com.zy.core.ThreadHandler;
@@ -20,26 +20,35 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
 
 @Slf4j
 @SuppressWarnings("all")
 public class FakeNyShuttleThread implements ThreadHandler {
 
-
     private RedisUtil redisUtil;
-    private JSONObject fakeStatusDemo = JSONObject.parseObject("{\"mode\":1,\"extend\":{\"countQuantity\":400,\"suspendState\":0,\"minCellVoltage\":3279,\"chargeCycleTimes\":0,\"maxCellVoltage\":3281,\"surplusQuantity\":204,\"voltage\":5248},\"hasLift\":false,\"hasPallet\":false,\"batteryVoltage\":5248,\"runDirection\":\"2\",\"currentCode\":\"{\\\"x\\\":12,\\\"y\\\":37,\\\"z\\\":3}\",\"errorCode\":\"0\",\"hasCharge\":false,\"batteryPower\":\"51\",\"speed\":0,\"deviceStatus\":1}");
-    private HashMap<String, Socket> fakeServerMap = new HashMap();
-    private HashMap<String, JSONObject> fakeStatusMap = new HashMap();
+    private JSONObject fakeStatusDemo = JSONObject.parseObject("{\"mode\":1,\"extend\":{\"countQuantity\":400,\"suspendState\":0,\"minCellVoltage\":3279,\"chargeCycleTimes\":0,\"maxCellVoltage\":3281,\"surplusQuantity\":204,\"voltage\":5248},\"hasLift\":false,\"hasPallet\":false,\"batteryVoltage\":5248,\"runDirection\":\"2\",\"currentCode\":\"{\\\"x\\\":19,\\\"y\\\":11,\\\"z\\\":2}\",\"errorCode\":\"0\",\"hasCharge\":false,\"batteryPower\":\"51\",\"speed\":0,\"deviceStatus\":1}");
+    private ServerSocket serverSocket;
+    private Integer gatewayPort;
+    private ConcurrentHashMap<String, Thread> fakeThreadMap = new ConcurrentHashMap();
+    private ConcurrentHashMap<String, Socket> fakeServerMap = new ConcurrentHashMap();
+    private ConcurrentHashMap<String, JSONObject> fakeStatusMap = new ConcurrentHashMap();
+    private ConcurrentHashMap<String, JSONObject> fakeCommandMap = new ConcurrentHashMap();
 
     private boolean fake = false;
 
-    public FakeNyShuttleThread(RedisUtil redisUtil) {
+    public FakeNyShuttleThread(RedisUtil redisUtil, Integer gatewayPort) {
         this.redisUtil = redisUtil;
+        this.gatewayPort = gatewayPort;
     }
 
     @Override
     public void run() {
         News.info("Fake Server is Started");
+
+        acceptorThread();
+        fakeCommandThread();
+
         while (true) {
             try {
                 initFakeDeviceServer();
@@ -49,61 +58,270 @@
         }
     }
 
-    private void initFakeDeviceServer() {
-        FakeDeviceUtils fakeDeviceUtils = SpringUtils.getBean(FakeDeviceUtils.class);
-        String fakeDeviceConfig = fakeDeviceUtils.getFakeDeviceConfig();
-        if(null != fakeDeviceConfig){
-            List<DeviceConfig> deviceConfigs = JSON.parseArray(fakeDeviceConfig, DeviceConfig.class);
-            for (DeviceConfig device : deviceConfigs) {
-                if (!device.getDeviceType().equals(String.valueOf(SlaveType.Shuttle))) {
-                    continue;
-                }
-
-                if (!device.getThreadImpl().equals("NyShuttleThread")) {
-                    continue;
-                }
-
-                if (fakeServerMap.containsKey(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo())) {
-                    continue;
-                }
-
-                Thread fakeThread = new Thread(() -> {
+    private void acceptorThread() {
+        Thread acceptorThread = new Thread(() -> {
+            log.info("{}:acceptorThread is start");
+            try {
+                while (true) {
                     try {
-                        ServerSocket serverSocket = new ServerSocket(device.getPort());
-                        Socket fakeSocket = serverSocket.accept();
-                        fakeServerMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeSocket);
-                        fakeStatusMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), JSON.parseObject(JSON.toJSONString(fakeStatusDemo)));
-                        while (true) {
-                            if(fakeSocket == null) {
-                                fakeServerMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
-                                break;
-                            }
-
-                            if(fakeSocket.isClosed()) {
-                                fakeSocket = null;
-                                continue;
-                            }
-
-                            handleClient(fakeSocket, device);
+                        if (serverSocket == null) {
+                            serverSocket = new ServerSocket(gatewayPort);
                         }
                     }catch (Exception e){
                         e.printStackTrace();
                     }
-                });
-                fakeThread.start();
 
-                // init
-                ThreadHandler thread = new NyShuttleThread(device, redisUtil);;
-                new Thread(thread).start();
-                SlaveConnection.put(SlaveType.Shuttle, device.getDeviceNo(), thread);
+                    if(serverSocket == null){
+                        continue;
+                    }
+
+                    Socket fakeSocket = serverSocket.accept();
+                    InputStream inputStream = fakeSocket.getInputStream();
+                    if(inputStream == null){
+                        continue;
+                    }
+                    // 鑾峰彇杈撳叆娴�
+                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+                    // 璇诲彇鏈嶅姟鍣ㄧ殑鍝嶅簲
+                    StringBuffer sb = new StringBuffer();
+                    char[] chars = new char[2048];//缂撳啿鍖�
+                    while (true) {
+                        reader.read(chars);
+                        String trim = new String(chars);
+                        sb.append(trim);
+                        if (trim.lastIndexOf("\r\n") != -1) {
+                            break;
+                        }
+                    }
+
+//                    log.info("acceptorThread is end:{}", sb.toString());
+                    JSONObject result = JSON.parseObject(sb.toString());
+                    if(result == null){
+                        continue;
+                    }
+
+                    Object msgType = result.get("msgType");
+                    if (msgType != null) {
+                        if ("fakeDeviceFirstConnect".equals(msgType)) {
+                            DeviceConfig device = JSON.parseObject(JSON.toJSONString(result.get("deviceConfig")), DeviceConfig.class);
+                            log.info("{}:device is start,devices:{}", device.getDeviceNo(),JSON.toJSONString(fakeServerMap));
+
+                            String fakeStatus = JSON.toJSONString(fakeStatusDemo);
+                            if (!Cools.isEmpty(device.getFakeInitStatus())) {
+                                fakeStatus = device.getFakeInitStatus();
+                            }
+
+                            fakeServerMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeSocket);
+                            fakeStatusMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), JSON.parseObject(fakeStatus));
+
+                            HashMap<String, Object> map = new HashMap<>();
+                            map.put("deviceNo", device.getDeviceNo());
+                            map.put("status", "success");
+                            // 鑾峰彇杈撳嚭娴�
+                            OutputStreamWriter writer = new OutputStreamWriter(fakeSocket.getOutputStream());
+                            writer.write(JSON.toJSONString(map) + "\r\n");
+                            writer.flush();
+                        }
+                    }
+
+                    Thread.sleep(1000);
+                }
+            }catch (Exception e){
+                e.printStackTrace();
             }
+        });
+        acceptorThread.start();
+    }
+
+    private void fakeCommandThread() {
+        Thread fakeCommandThread = new Thread(() -> {
+            while (true) {
+                try {
+                    FakeDeviceUtils fakeDeviceUtils = null;
+                    try {
+                        fakeDeviceUtils = SpringUtils.getBean(FakeDeviceUtils.class);
+                    }catch (Exception e){}
+                    if(fakeDeviceUtils == null){
+                        continue;
+                    }
+                    List<DeviceConfig> deviceConfigs = fakeDeviceUtils.getFakeDeviceConfig();
+                    for (DeviceConfig device : deviceConfigs) {
+                        excuteFakeCommand(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        });
+        fakeCommandThread.start();
+    }
+
+    private synchronized void initFakeDeviceServer() {
+        FakeDeviceUtils fakeDeviceUtils = null;
+        try {
+            fakeDeviceUtils = SpringUtils.getBean(FakeDeviceUtils.class);
+        }catch (Exception e){}
+        if(fakeDeviceUtils == null){
+            return;
+        }
+        List<DeviceConfig> deviceConfigs = fakeDeviceUtils.getFakeDeviceConfig();
+        for (DeviceConfig device : deviceConfigs) {
+            if (!device.getDeviceType().equals(String.valueOf(SlaveType.Shuttle))) {
+                continue;
+            }
+
+            if (!device.getThreadImpl().equals("NyShuttleThread")) {
+                continue;
+            }
+
+            if (fakeThreadMap.containsKey(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo())) {
+                continue;
+            }
+
+            log.info("{}:device is run,devices:{}", device.getDeviceNo(),JSON.toJSONString(fakeServerMap));
+
+            Thread fakeThread = new Thread(() -> {
+                log.info("{}:device is start handle client", device.getDeviceNo());
+                try {
+                    while (true) {
+                        if(fakeServerMap.containsKey(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo())){
+                            handleClient(device);
+                        }
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            });
+            fakeThread.start();
+            fakeThreadMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeThread);
+
+            // init
+            ThreadHandler thread = new NyShuttleThread(device, redisUtil);;
+            new Thread(thread).start();
+            SlaveConnection.put(SlaveType.Shuttle, device.getDeviceNo(), thread);
         }
     }
 
-    private void handleClient(Socket socket, DeviceConfig device) throws IOException {
+    private void excuteFakeCommand(String key) {
+        if (!fakeCommandMap.containsKey(key)) {
+            return;
+        }
+        JSONObject command = fakeCommandMap.get(key);
+        fakeCommandMap.remove(key);
+        new Thread(() -> {
+            try {
+                JSONObject fakeStatus = fakeStatusMap.get(key);
+                String commandType = command.getString("commandType");
+                if (commandType == null) {
+                    return;
+                }
+
+                if (commandType.equals("liftUp")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+
+                    //delay
+                    Thread.sleep(2000);
+                    fakeStatus.put("hasLift", true);
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }else if (commandType.equals("liftDown")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+
+                    //delay
+                    Thread.sleep(2000);
+                    fakeStatus.put("hasLift", false);
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }else if (commandType.equals("charge")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+
+                    //delay
+                    Thread.sleep(2000);
+                    fakeStatus.put("hasCharge", true);
+
+                    Integer batteryPower = Integer.parseInt(fakeStatus.getString("batteryPower"));
+                    while (true) {
+                        Thread.sleep(10000);
+                        batteryPower = batteryPower + 1;
+                        fakeStatus.put("batteryPower", batteryPower);
+                        fakeStatusMap.put(key, fakeStatus);
+                        if(batteryPower >= 100) {
+                            break;
+                        }
+                    }
+
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }else if (commandType.equals("stopCharge")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+
+                    //delay
+                    Thread.sleep(2000);
+                    fakeStatus.put("hasCharge", false);
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }else if (commandType.equals("updateFloor")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+
+                    //delay
+                    Thread.sleep(2000);
+
+                    JSONObject body = command.getJSONObject("commandBody");
+                    String currentCode = fakeStatus.getString("currentCode");
+                    JSONObject point = JSON.parseObject(currentCode);
+                    point.put("z", body.getInteger("z"));
+                    fakeStatus.put("currentCode", JSON.toJSONString(point));
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }else if (commandType.equals("move")) {
+                    fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                    fakeStatusMap.put(key, fakeStatus);
+                    Thread.sleep(2000);
+
+                    JSONObject body = command.getJSONObject("commandBody");
+                    String pathList = body.getString("path");
+                    List<JSONObject> list = JSON.parseArray(pathList, JSONObject.class);
+                    for (JSONObject path : list) {
+                        String currentCode = fakeStatus.getString("currentCode");
+                        JSONObject point = JSON.parseObject(currentCode);
+                        point.put("x", path.getInteger("xp"));
+                        point.put("y", path.getInteger("yp"));
+                        point.put("z", path.getInteger("z"));
+                        fakeStatus.put("currentCode", JSON.toJSONString(point));
+                        fakeStatus.put("deviceStatus", 0);//璁惧蹇欑
+                        fakeStatusMap.put(key, fakeStatus);
+                        Thread.sleep(2000);
+                    }
+
+                    fakeStatus.put("deviceStatus", 1);//璁惧绌洪棽
+                    fakeStatusMap.put(key, fakeStatus);
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }).start();
+    }
+
+    private void handleClient(DeviceConfig device) throws IOException {
         try {
+            Socket socket = fakeServerMap.get(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+            if (socket == null) {
+                removeFake(device);
+                return;
+            }
+            InputStream inputStream = socket.getInputStream();
+            if(inputStream == null){
+                removeFake(device);
+                return;
+            }
+
             // 鑾峰彇杈撳叆娴�
-            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
             // 璇诲彇鏈嶅姟鍣ㄧ殑鍝嶅簲
             StringBuffer sb = new StringBuffer();
             char[] chars = new char[2048];//缂撳啿鍖�
@@ -117,13 +335,23 @@
             }
 
             JSONObject result = JSON.parseObject(sb.toString());
-            log.info("鏀跺埌Client Data: {}", JSON.toJSONString(result));
+//            log.info("鏀跺埌Client Data: {}", JSON.toJSONString(result));
             processCommand(result, device);
         } catch (Exception e) {
-//            e.printStackTrace();
-            socket.close();
-            fakeServerMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+            e.printStackTrace();
         }
+    }
+
+    private void removeFake(DeviceConfig device) {
+        Thread thread = fakeThreadMap.get(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+        if (thread != null) {
+            thread.interrupt();
+        }
+
+        fakeThreadMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+        fakeServerMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+        fakeStatusMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
+        fakeCommandMap.remove(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
     }
 
     public void processCommand(JSONObject result, DeviceConfig device) throws IOException {
@@ -131,40 +359,38 @@
         JSONObject fakeStatus = fakeStatusMap.get(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo());
 
         JSONObject request = result.getJSONObject("request");
+        JSONObject header = request.getJSONObject("header");
         JSONObject body = request.getJSONObject("body");
+
+        Integer requestId = header.getInteger("requestId");
         String requestType = body.getString("requestType");
         Integer taskId = body.getInteger("taskId");
+
+        JSONObject fakeCommand = new JSONObject();
+        fakeCommand.put("deviceNo", device.getDeviceNo());
+        fakeCommand.put("deviceType", device.getDeviceType());
+        fakeCommand.put("commandType", requestType);
+        fakeCommand.put("commandBody", body);
         if (requestType.equals("liftUp")) {
-            fakeStatus.put("hasLift", true);
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("liftDown")) {
-            fakeStatus.put("hasLift", false);
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("charge")) {
-            fakeStatus.put("hasCharge", true);
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("stopCharge")) {
-            fakeStatus.put("hasCharge", false);
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("updateFloor")) {
-            String currentCode = fakeStatus.getString("currentCode");
-            JSONObject point = JSON.parseObject(currentCode);
-            point.put("z", body.getInteger("z"));
-            fakeStatus.put("currentCode", JSON.toJSONString(point));
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("move")) {
-            String pathList = body.getString("path");
-            List<JSONObject> list = JSON.parseArray(pathList, JSONObject.class);
-            for (JSONObject path : list) {
-                String currentCode = fakeStatus.getString("currentCode");
-                JSONObject point = JSON.parseObject(currentCode);
-                point.put("x", path.getInteger("xp"));
-                point.put("y", path.getInteger("yp"));
-                point.put("z", path.getInteger("z"));
-                fakeStatus.put("currentCode", JSON.toJSONString(point));
-                try {
-                    Thread.sleep(1);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
+            fakeCommandMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeCommand);
+            response = genereateFakeCommandResponse(requestId, taskId, requestType);
         } else if (requestType.equals("readState")) {
-            response = genereateFakeStatusResponse(taskId, fakeStatus);
+            response = genereateFakeStatusResponse(requestId, fakeStatus, device.getDeviceNo());
         }
 
         fakeStatusMap.put(String.valueOf(SlaveType.Shuttle) + device.getDeviceNo(), fakeStatus);
@@ -176,11 +402,11 @@
         }
     }
 
-    public String genereateFakeStatusResponse(Integer taskId, JSONObject fakeStatus) {
+    public String genereateFakeStatusResponse(Integer taskId, JSONObject fakeStatus, Integer deviceNo) {
         JSONObject result = new JSONObject();
         JSONObject response = new JSONObject();
         result.put("msgType", "responseMsg");
-        result.put("robotId", 5001);
+        result.put("robotId", deviceNo);
         result.put("response", response);
 
         JSONObject header = new JSONObject();
@@ -197,7 +423,10 @@
         body.put("point", fakeStatus.getString("currentCode"));
         body.put("powerPercent", fakeStatus.getString("batteryPower"));
         body.put("voltage", fakeStatus.getInteger("batteryVoltage"));
-        body.put("errCode", new ArrayList<Integer>(){{add(fakeStatus.getInteger("errorCode"));add(0);}});
+        body.put("errCode", new ArrayList<Integer>() {{
+            add(fakeStatus.getInteger("errorCode"));
+            add(0);
+        }});
         body.put("liftPosition", fakeStatus.getBoolean("hasLift") == true ? 2 : 1);
         body.put("loadState", fakeStatus.getBoolean("hasPallet") == true ? 1 : 0);
         body.put("runDir", fakeStatus.getString("runDirection"));
@@ -215,6 +444,27 @@
         return JSON.toJSONString(result);
     }
 
+    public String genereateFakeCommandResponse(Integer responseId, Integer taskId, String commandType) {
+        JSONObject result = new JSONObject();
+        JSONObject response = new JSONObject();
+        result.put("msgType", "responseMsg");
+        result.put("robotId", 5001);
+        result.put("response", response);
+
+        JSONObject header = new JSONObject();
+        JSONObject body = new JSONObject();
+        response.put("header", header);
+        response.put("body", body);
+
+        header.put("responseId", responseId);
+        header.put("version", "GV-APP-F427-N24036-1112");
+
+        body.put("responseType", commandType);
+        body.put("result", "success");
+        body.put("taskId", taskId);
+        return JSON.toJSONString(result);
+    }
+
     @Override
     public boolean connect() {
         return true;

--
Gitblit v1.9.1