diff --git a/web/src/main/java/com/zhehekeji/web/service/InitService.java b/web/src/main/java/com/zhehekeji/web/service/InitService.java index 3f621a6..8d05a11 100644 --- a/web/src/main/java/com/zhehekeji/web/service/InitService.java +++ b/web/src/main/java/com/zhehekeji/web/service/InitService.java @@ -113,7 +113,7 @@ public class InitService implements ApplicationRunner { } TaskDelayExecutor.runMp4DownloadExecutor(); - GetPhotoDelayExecutor.runExecutor(); + GetPhotoDelayExecutor.runExecutor(streets); } class LoginThread extends Thread{ diff --git a/web/src/main/java/com/zhehekeji/web/service/PlcService.java b/web/src/main/java/com/zhehekeji/web/service/PlcService.java index 550104c..c9d1f21 100644 --- a/web/src/main/java/com/zhehekeji/web/service/PlcService.java +++ b/web/src/main/java/com/zhehekeji/web/service/PlcService.java @@ -42,6 +42,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; +import static com.zhehekeji.web.service.client.GetPhotoDelayExecutor.cameraDelayTaskMap; + /** * @Description plc信号指令处理类 @@ -734,22 +736,25 @@ public class PlcService { if (lock.tryLock()) { //队列中没有任务,发送取图指令 //只采用队列,队列中有数据则自动发送 - if (GetPhotoDelayExecutor.cameraDelayTasks.size() == 0 && ClientChanel.get(dataInfo.getSRMNumber()) != null) { - ClientChanel.get(street.getPlcId()).writeAndFlush(transmissionPojo.toString(TransmissionType.GPS)); - } + //模拟随行 + if (configProperties.isInventorySimulationFollow()) { + + String s = (new TransmissionPojo(street, transmissionPojo.getRow(),transmissionPojo.getColumn(),transmissionPojo.getDirection(), "")).toString(TransmissionType.GPS); + + //放置到队列中,等待取图返回后删除 + GetPhotoDelayExecutor.addCameraDelayTask(street.getPlcId(), s, configProperties.getQueueSpanTime()); + + + } //放置到队列中,等待取图返回后删除 GetPhotoDelayExecutor.addCameraDelayTask(street.getPlcId(), transmissionPojo.toString(TransmissionType.GPS), configProperties.getQueueSpanTime()); } - if (configProperties.isInventorySimulationFollow()) { - ClientChanel.get(dataInfo.getSRMNumber()).writeAndFlush( - (new TransmissionPojo(street, transmissionPojo.getRow(), transmissionPojo.getColumn(), transmissionPojo.getDirection(), "")).toString(TransmissionType.GPS)); - - } } catch (InterruptedException e) { log.error("取图命令 error", e); } finally { lock.unlock(); + log.info("盘点完成"); } // ClientChanel.get(dataInfo.getSRMNumber()).writeAndFlush(); @@ -800,19 +805,23 @@ public class PlcService { public KsecInfo getKsecDataInfo(TransmissionPojo transmissionPojo, String type) { KsecDataInfo ksecDataInfo = new KsecDataInfo(); CheckLog checkLog = checkLogMapper.selectById(transmissionPojo.getCheckId()); - ksecDataInfo.setLotnum(checkLog.getLotnum()); - ksecDataInfo.setSRMNumber(transmissionPojo.getStreetNumber()); - ksecDataInfo.setCmdName(type); - ksecDataInfo.setTaskId(checkLog.getTaskId().toString()); - ksecDataInfo.setFromDirection(checkLog.getDirection()); - ksecDataInfo.setFromColumn(checkLog.getColumn()); - ksecDataInfo.setFromRow(checkLog.getRow()); - ksecDataInfo.setFromSide(checkLog.getSide()); - ksecDataInfo.setCode(checkLog.getCode()); - ksecDataInfo.setTrayCode(checkLog.getTrayCode()); - ksecDataInfo.setLotnum(checkLog.getLotnum()); + if(checkLog!=null) { + ksecDataInfo.setLotnum(checkLog.getLotnum()); + ksecDataInfo.setSRMNumber(transmissionPojo.getStreetNumber()); + ksecDataInfo.setCmdName(type); + ksecDataInfo.setTaskId(checkLog.getTaskId().toString()); + ksecDataInfo.setFromDirection(checkLog.getDirection()); + ksecDataInfo.setFromColumn(checkLog.getColumn()); + ksecDataInfo.setFromRow(checkLog.getRow()); + ksecDataInfo.setFromSide(checkLog.getSide()); + ksecDataInfo.setCode(checkLog.getCode()); + ksecDataInfo.setTrayCode(checkLog.getTrayCode()); + ksecDataInfo.setLotnum(checkLog.getLotnum()); + + } + KsecInfo ksecInfo = new KsecInfo("KC", "E", ksecDataInfo); return ksecInfo; } diff --git a/web/src/main/java/com/zhehekeji/web/service/client/Decoder.java b/web/src/main/java/com/zhehekeji/web/service/client/Decoder.java index 2648807..3874cb1 100644 --- a/web/src/main/java/com/zhehekeji/web/service/client/Decoder.java +++ b/web/src/main/java/com/zhehekeji/web/service/client/Decoder.java @@ -24,6 +24,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import static com.zhehekeji.web.service.client.GetPhotoDelayExecutor.cameraDelayTaskMap; + /** * 客户端解码器 连接用 */ @@ -101,6 +103,8 @@ public class Decoder extends DelimiterBasedFrameDecoder { else if(GET_PHOTO_END.equals(transmissionPojo.getHeader())){ if(transmissionPojo.getTaskId() != null && !"0".equals(transmissionPojo.getTaskId())) { ClientChanel.get(transmissionPojo.getStreetNumber()).writeAndFlush(transmissionPojo.toString(TransmissionType.RTS)); + + // GetPhotoDelayExecutor.addCameraDelayTask(transmissionPojo.getStreetNumber(), transmissionPojo.toString(TransmissionType.RTS), 3000); } try { Thread.sleep(50L); @@ -109,8 +113,8 @@ public class Decoder extends DelimiterBasedFrameDecoder { } //删除队列的拍照数据 GetPhotoDelayExecutor.remove(transmissionPojo.getStreetNumber(),transmissionPojo.toString(TransmissionType.GPS)); - //发送给上位机 - CameraDelayTask cameraDelayTask = GetPhotoDelayExecutor.getNext(transmissionPojo.getStreetNumber()); + //读取下一个发送 + CameraDelayTask cameraDelayTask = GetPhotoDelayExecutor.nextOne(transmissionPojo.getStreetNumber(),transmissionPojo.toString(TransmissionType.GPS)); if (cameraDelayTask != null) { TransmissionPojo pojo = new TransmissionPojo(cameraDelayTask.getCommand()); ClientChanel.get(pojo.getStreetNumber()).writeAndFlush(pojo.toString(TransmissionType.GPS)); diff --git a/web/src/main/java/com/zhehekeji/web/service/client/GetPhotoDelayExecutor.java b/web/src/main/java/com/zhehekeji/web/service/client/GetPhotoDelayExecutor.java index aab1719..7f3c4b1 100644 --- a/web/src/main/java/com/zhehekeji/web/service/client/GetPhotoDelayExecutor.java +++ b/web/src/main/java/com/zhehekeji/web/service/client/GetPhotoDelayExecutor.java @@ -1,23 +1,29 @@ package com.zhehekeji.web.service.client; import com.zhehekeji.common.util.SpringContextUtil; +import com.zhehekeji.web.entity.Street; import com.zhehekeji.web.lib.CameraControlModule; import com.zhehekeji.web.lib.CameraDelayTask; import com.zhehekeji.web.lib.TaskDelayExecutor; import com.zhehekeji.web.service.PlcService; import com.zhehekeji.web.service.ksec.KsecInfo; import com.zhehekeji.web.service.ksec.KsecNettyClient; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.*; /** * GetPhotoDelayExecutor类用于管理照片获取的延时任务。 */ +@Slf4j public class GetPhotoDelayExecutor { // 延时队列,存放CameraDelayTask任务 - public static DelayQueue cameraDelayTasks = new DelayQueue<>(); + public static Map> cameraDelayTaskMap = new ConcurrentHashMap<>(); // 线程池,用于执行延时任务 - private static ExecutorService exec = Executors.newFixedThreadPool(1); + private static ExecutorService exec = Executors.newFixedThreadPool(10); /** * 向延时队列中添加一个拍照延时任务。 @@ -28,8 +34,23 @@ public class GetPhotoDelayExecutor { */ public static void addCameraDelayTask(String cameraPlcId, String getPhotoCommand, long time) { + if(cameraDelayTaskMap.get(cameraPlcId)==null || cameraDelayTaskMap.get(cameraPlcId).size() == 0) { + if( ClientChanel.get(cameraPlcId) != null){ + log.info("队列中无数据,输出"+getPhotoCommand); + ClientChanel.get(cameraPlcId).writeAndFlush(getPhotoCommand); + }else { + + log.info("队列中无数据,未找到通信"+cameraPlcId); + } + } CameraDelayTask cameraDelayTask = new CameraDelayTask(cameraPlcId, getPhotoCommand, time); - cameraDelayTasks.add(cameraDelayTask); + if(cameraDelayTaskMap.get(cameraPlcId)!=null){ + + cameraDelayTaskMap.get(cameraPlcId).add(cameraDelayTask); + }else { + cameraDelayTaskMap.put(cameraPlcId,new DelayQueue<>()); + cameraDelayTaskMap.get(cameraPlcId).add(cameraDelayTask); + } } /** @@ -38,47 +59,57 @@ public class GetPhotoDelayExecutor { * @param getPhotoCommand 获取巷道编号 * @param cameraPlcId 命令行 */ - public static void remove(String getPhotoCommand, String cameraPlcId) { + public static CameraDelayTask remove(String cameraPlcId, String getPhotoCommand) { cameraPlcId = cameraPlcId.intern(); synchronized (cameraPlcId) { // 将延时队列中的任务转换为数组,便于遍历和移除 - Object[] cameraDelayTask = cameraDelayTasks.toArray(); - for (Object cameraDelayTask1 : cameraDelayTask) { - CameraDelayTask cameraDelayTask2 = (CameraDelayTask) cameraDelayTask1; - if (cameraDelayTask2.getCameraPlcId().equals(getPhotoCommand)) { - cameraDelayTasks.remove(cameraDelayTask2); + Object[] objects = cameraDelayTaskMap.get(cameraPlcId).toArray(); + if(objects.length > 0) { + CameraDelayTask cameraDelayTask = (CameraDelayTask)objects[0]; + + if (cameraDelayTask != null) { + cameraDelayTaskMap.get(cameraPlcId).remove(cameraDelayTask); + return cameraDelayTask; + } } } + return null; } - /** - * 获取延时队列中最早的任务,并将其从队列中移除。 - * - * @param cameraPlcId 相机的PLC编号,该参数未被使用 - * @return 返回最早的任务,如果队列为空则返回null - */ - public static CameraDelayTask getNext(String cameraPlcId) { - Object[] cameraDelayTask = cameraDelayTasks.toArray(); - if (cameraDelayTask.length > 0) { - CameraDelayTask cameraDelayTask2 = (CameraDelayTask) cameraDelayTask[0]; - return cameraDelayTask2; + public static CameraDelayTask nextOne(String cameraPlcId, String getPhotoCommand) { + cameraPlcId = cameraPlcId.intern(); + synchronized (cameraPlcId) { + // 将延时队列中的任务转换为数组,便于遍历和移除 + Object[] objects = cameraDelayTaskMap.get(cameraPlcId).toArray(); + if(objects.length > 0) { + CameraDelayTask cameraDelayTask = (CameraDelayTask)objects[0]; + if (cameraDelayTask != null) { + return cameraDelayTask; + + } + } } return null; - } - /** * 启动延时任务的执行器。 */ - public static void runExecutor() { - exec.execute(new GetPhotoDelayExecutor.Consumer()); + public static void runExecutor(List streets ) { + for (Street street: streets){ + + exec.execute(new GetPhotoDelayExecutor.Consumer(street)); + } } /** * Consumer内部类,实现Runnable接口,用于消费延时队列中的任务。 */ private static class Consumer implements Runnable { + private Street street; + Consumer(Street street){ + this.street = street; + } /** * 无限循环,不断从延时队列中取出任务并执行。 */ @@ -89,17 +120,20 @@ public class GetPhotoDelayExecutor { // 从Spring上下文中获取PlcService实例 PlcService plcService = SpringContextUtil.getBean(PlcService.class); // 从延时队列中获取并移除一个任务 - CameraDelayTask cameraDelayTask = cameraDelayTasks.take(); - if(cameraDelayTask != null) { - // 构造传输对象,并将任务命令等信息设置进去 - TransmissionPojo transmissionPojo = new TransmissionPojo(cameraDelayTask.getCommand()); - // 调用PLC服务,模拟发送数据到上位机 - KsecInfo ksecInfo = plcService.getKsecDataInfo(transmissionPojo, "E"); - ksecInfo.getData().setTypeNum(transmissionPojo.getCategory()); - ksecInfo.getData().setQuantity(transmissionPojo.getCount()); - ksecInfo.getData().setCheckRlt(0); - // 将信息发送给上位机 - KsecNettyClient.write(ksecInfo); + if(cameraDelayTaskMap.get(street.getPlcId())!= null) { + CameraDelayTask cameraDelayTask = cameraDelayTaskMap.get(street.getPlcId()).take(); + if (cameraDelayTask != null) { + // 构造传输对象,并将任务命令等信息设置进去 + TransmissionPojo transmissionPojo = new TransmissionPojo(cameraDelayTask.getCommand()); + // 调用PLC服务,模拟发送数据到上位机 + KsecInfo ksecInfo = plcService.getKsecDataInfo(transmissionPojo, "E"); + ksecInfo.getData().setTypeNum(transmissionPojo.getCategory()); + ksecInfo.getData().setQuantity(transmissionPojo.getCount()); + ksecInfo.getData().setCheckRlt(0); + // 将信息发送给上位机 + if (!transmissionPojo.getTaskId().equals("0")) + KsecNettyClient.write(ksecInfo); + } } } catch (InterruptedException e) { e.printStackTrace(); diff --git a/web/src/main/resources/application-prod.yml b/web/src/main/resources/application-prod.yml index 92ec1d1..0c398f8 100644 --- a/web/src/main/resources/application-prod.yml +++ b/web/src/main/resources/application-prod.yml @@ -98,4 +98,4 @@ deleteFileDays: 30 productDoc: "C:/Users/昊天/Desktop/新建 文本文档 (3).txt" -inventorySimulationFollow: false \ No newline at end of file +inventorySimulationFollow: true \ No newline at end of file