diff --git a/web/src/main/java/com/zhehekeji/web/config/WebSocketConfig.java b/web/src/main/java/com/zhehekeji/web/config/WebSocketConfig.java index da266fc..e69de29 100644 --- a/web/src/main/java/com/zhehekeji/web/config/WebSocketConfig.java +++ b/web/src/main/java/com/zhehekeji/web/config/WebSocketConfig.java @@ -1,17 +0,0 @@ -package com.zhehekeji.web.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.server.standard.ServerEndpointExporter; - -@Configuration -public class WebSocketConfig { - /** - * 如果使用Springboot默认内置的tomcat容器,则必须注入ServerEndpoint的bean; - * 如果使用外置的web容器,则不需要提供ServerEndpointExporter,下面的注入可以注解掉 - */ - @Bean - public ServerEndpointExporter serverEndpointExporter(){ - return new ServerEndpointExporter(); - } -} diff --git a/web/src/main/java/com/zhehekeji/web/controller/StockController.java b/web/src/main/java/com/zhehekeji/web/controller/StockController.java index 10ea002..1e768ae 100644 --- a/web/src/main/java/com/zhehekeji/web/controller/StockController.java +++ b/web/src/main/java/com/zhehekeji/web/controller/StockController.java @@ -155,8 +155,12 @@ public class StockController { log.info("stockCheck:res:{}",stock); CheckInfo checkInfo= new CheckInfo(); if (stock!=null) { - checkInfo.setTrayCode(stock.getWmsTrayCode()); + checkInfo.setTrayCode(stock.getTrayCode()); checkInfo.setCheckRlt(stock.getStatus() == 2 || stock.getStatus() == 3 ? 1 : 0); + checkInfo.setExportTime(stock.getExportTime()); + checkInfo.setOrderNum(stock.getCheckNum().substring(stock.getCheckNum().lastIndexOf("_") + 1)); + checkInfo.setWmsTrayCode(stock.getWmsTrayCode()); + checkInfo.setWmsTrayCodes(stock.getCode().split(",")); }else { checkInfo.setCheckRlt(0); diff --git a/web/src/main/java/com/zhehekeji/web/controller/TestController.java b/web/src/main/java/com/zhehekeji/web/controller/TestController.java index ba47b73..a1658f6 100644 --- a/web/src/main/java/com/zhehekeji/web/controller/TestController.java +++ b/web/src/main/java/com/zhehekeji/web/controller/TestController.java @@ -3,9 +3,8 @@ package com.zhehekeji.web.controller; import com.zhehekeji.core.pojo.Result; import com.zhehekeji.web.entity.RFID; import com.zhehekeji.web.entity.Street; -import com.zhehekeji.web.service.PlcCmdInfo; import com.zhehekeji.web.service.RFID.RFIDMap; -import com.zhehekeji.web.service.RFID.RFIDSocket; +import com.zhehekeji.web.service.RFID.RFIDTCPClient; import com.zhehekeji.web.service.RFIDService; import com.zhehekeji.web.service.StreetService; import com.zhehekeji.web.service.TestService; @@ -16,7 +15,6 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.HashSet; -import java.util.List; import java.util.Set; @Api(value = "TestController",tags = "扫码测试") @@ -46,77 +44,59 @@ public class TestController { @GetMapping("/1") public Result test(){ - RFIDSocket rfidSocket = new RFIDSocket("127.0.0.1", 4001); - rfidSocket.startCheck(1,true); - try { - Thread.sleep(1000*15); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - rfidSocket.stopCheck(); - System.out.println(rfidSocket.getTags()); + return Result.success(); } + @Resource StreetService streetService; @Resource RFIDService rfidService; @ApiOperation("rfid") @GetMapping("/rfid") - public Result> rfid(@PathVariable String streetId){ + public Result> rfid(@RequestParam String streetId){ Street street = streetService.getStreetByPlcId(streetId); - RFIDSocket rfidSocket = new RFIDSocket(street.getPlcIp(), 4001); - rfidSocket.startCheck(1,true); - try { - Thread.sleep(1000*15); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - rfidSocket.stopCheck(); - System.out.println(rfidSocket.getTags()); - return Result.success(rfidSocket.getTags()); + return Result.success(); } @ApiOperation("rfidNew") @GetMapping("/rfidNew") - public Result> rfidNew(@PathVariable String streetId) { + public Result> rfidNew(@RequestParam String streetId) { Street street = streetService.getStreetByPlcId(streetId); if (street != null) { //rfid不分左右,rfid使用同一ip和端口,依靠传递字符调整方向 RFID rfid = rfidService.getRFIDByPlc(street.getId(), null); if (rfid != null) { - RFIDStart(rfid.getIp(), rfid.getPort(), street.getId(), 1); - try { - Thread.sleep(1000*15); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - Set tags = RFIDStop(street); - return Result.success(tags); + return Result.success(); } } return Result.success(new HashSet<>()); } - public void RFIDStart(String ip, Integer port, Integer streetId, Integer direction) { - RFIDSocket rfidSocket = new RFIDSocket(ip, port); - log.info("rfid调用,ip:" + ip + ";port:" + port); - rfidSocket.startCheck(direction,false); - RFIDMap.put(streetId, rfidSocket); - } + @ApiOperation("rfidNewTid") + @GetMapping("/rfidNewTid") + public Result> rfidNewTid(@RequestParam String streetId) { + Street street = streetService.getStreetByPlcId(streetId); + if (street != null) { + //rfid不分左右,rfid使用同一ip和端口,依靠传递字符调整方向 + RFID rfid = rfidService.getRFIDByPlc(street.getId(), null); + if (rfid != null) { - public Set RFIDStop(Street street) { - RFIDSocket rfidSocket = RFIDMap.get(street.getId()); - Set tags = null; - if (rfidSocket != null) { - tags = rfidSocket.getTags(); - log.info("tags:{}", tags); - rfidSocket.stopCheck(); - RFIDMap.remove(street.getId()); + Set tags = RFIDStartTid(rfid.getIp(), rfid.getPort(), street.getId(), 1); + return Result.success(tags); + } } + + return Result.success(new HashSet<>()); + } + + public Set RFIDStartTid(String ip, Integer port, Integer streetId, Integer direction) { + + Set tags = RFIDTCPClient.checkTid(ip, port); return tags; } + } diff --git a/web/src/main/java/com/zhehekeji/web/entity/CheckInfo.java b/web/src/main/java/com/zhehekeji/web/entity/CheckInfo.java index 837cbab..db8fd0d 100644 --- a/web/src/main/java/com/zhehekeji/web/entity/CheckInfo.java +++ b/web/src/main/java/com/zhehekeji/web/entity/CheckInfo.java @@ -1,9 +1,18 @@ package com.zhehekeji.web.entity; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; +import java.time.LocalDateTime; +import java.util.Set; + @Data public class CheckInfo { private String trayCode; + private String wmsTrayCode; + private String[] wmsTrayCodes; + private String orderNum; + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") + private LocalDateTime exportTime; private int checkRlt; } 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 c87f53d..03dbce9 100644 --- a/web/src/main/java/com/zhehekeji/web/service/PlcService.java +++ b/web/src/main/java/com/zhehekeji/web/service/PlcService.java @@ -1,45 +1,30 @@ package com.zhehekeji.web.service; -import codeDetector.BarcodeDetector; -import com.alibaba.druid.support.json.JSONUtils; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.zhehekeji.common.util.PathUtil; import com.zhehekeji.web.config.ConfigProperties; -import com.zhehekeji.web.config.WebSocketConfig; import com.zhehekeji.web.entity.*; import com.zhehekeji.web.lib.*; import com.zhehekeji.web.mapper.*; import com.zhehekeji.web.pojo.OrderVO; import com.zhehekeji.web.pojo.websocket.WebSocketVo; -import com.zhehekeji.web.service.RFID.RFIDMap; -import com.zhehekeji.web.service.RFID.RFIDSocket; -import com.zhehekeji.web.service.RFID.RFIDSocketOld; -import com.zhehekeji.web.service.hikLightSource.HikControlSocket; import com.zhehekeji.web.service.interfaces.RfidLiveService; -import com.zhehekeji.web.service.ksec.KsecNettyClient; -import com.zhehekeji.web.service.sick.SickSocket; -import com.zhehekeji.web.util.ToolUtil; import com.zhehekeji.web.ws.WebSocketServer; -import io.swagger.models.auth.In; +import jdk.internal.joptsimple.internal.Strings; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.SetUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.poi.util.ArrayUtil; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.Resource; -import java.io.File; -import java.io.FileWriter; import java.io.IOException; import java.time.Duration; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.*; -import java.util.stream.Collectors; + +import static com.zhehekeji.web.service.RFID.RFIDTCPClient.checkTid; /** * @Description plc信号指令处理类 @@ -654,55 +639,52 @@ public class PlcService { Boolean trayRFIDCheck = Boolean.FALSE; - Future rfidFuture = executor.submit(() -> { - long startRfidTime = System.currentTimeMillis(); - Boolean flag = Boolean.FALSE;; + long startRfidTime = System.currentTimeMillis(); + Boolean flag = Boolean.FALSE; + ; - Set tags = new HashSet<>(); - try { - RFIDCheck(plcCmdInfo, true); - Thread.sleep(1000 * configProperties.getRfid().getScanTime()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - tags = RFIDStop(plcCmdInfo); - log.info("盘点rfid扫描结果:" + tags); - } - if (tags != null && tags.size() > 0) { - - if ( wmsTrayCode != null - && tags.contains(wmsTrayCode)) { - log.info("扫描成功"); - flag = Boolean.TRUE; - } else { + Set tags = new HashSet<>(); + try { + tags = RFIDCheck(plcCmdInfo, true); + Thread.sleep(1000 * configProperties.getRfid().getScanTime()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + log.info("盘点rfid扫描结果:" + tags); + } + if (tags != null && tags.size() > 0) { - flag = Boolean.FALSE;; - } - RFID rfid = rfidMapper.selectOne(new QueryWrapper().eq("street_id", street.getId())); - if (!rfidLiveService.getRfidLive(plcCmdInfo, street, wmsTrayCode)) { - rfidLiveService.rfidRemoveLive(plcCmdInfo, street, rfid); - } - rfidLiveService.rfidSave(plcCmdInfo, String.join(",", tags), street, rfid); - } + if (wmsTrayCode != null + && tags.contains(wmsTrayCode)) { + log.info("扫描成功"); + flag = Boolean.TRUE; + } else { - long endRfidTime = System.currentTimeMillis(); + flag = Boolean.FALSE; + ; + } + RFID rfid = rfidMapper.selectOne(new QueryWrapper().eq("street_id", street.getId())); + if (!rfidLiveService.getRfidLive(plcCmdInfo, street, wmsTrayCode)) { + rfidLiveService.rfidRemoveLive(plcCmdInfo, street, rfid); + } + rfidLiveService.rfidSave(plcCmdInfo, String.join(",", tags), street, rfid); + } - log.info("rfid time:{}millisecond", startRfidTime - endRfidTime); - return flag; + long endRfidTime = System.currentTimeMillis(); - }); - try { + log.info("rfid time:{}millisecond", startRfidTime - endRfidTime); // String sickCode = sickFuture.get(); // get()会阻塞直到结果可用 - Boolean rfid = rfidFuture.get(); // get()会阻塞直到结果可用 - log.info("rfid:{}", rfid); + Boolean rfid = flag; // get()会阻塞直到结果可用 + log.info("rfid:{}", rfid); - trayRFIDCheck = rfid; + trayRFIDCheck = rfid; - - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); + if (tags == null) { + tags = new HashSet<>(); } + String tagStr = String.join(",", tags); + log.info("rfid tagsStr:{}", tagStr); OrderInfo orderInfo = new OrderInfo(street, plcCmdInfo, 1, cmdCode); Stock stock = stockMapper.getByStreetAndDirectionAndSideAndRowColumn(orderInfo.getStreetId(), plcCmdInfo.getFromDirection(), orderInfo.getSeparation(), orderInfo.getRow(), orderInfo.getColumn()); String scanCode = null; @@ -711,23 +693,24 @@ public class PlcService { //核对异常 Integer status = 1; //托盘和货物都正确 - if ( trayRFIDCheck) { + if (trayRFIDCheck) { status = 2; - trayCode=wmsTrayCode; - }else { - trayCode="盘点失败"; + trayCode = wmsTrayCode; + } else { + trayCode = "盘点失败"; } if (stock == null) { stock = Stock.builder() .checkNum(plcCmdInfo.getOrderNum()) .lotnum(plcCmdInfo.getLotnum()) - .code(scanCode) +// .code(scanCode) .wmsCode(wmsCode) .wmsTrayCode(wmsTrayCode) .trayCode(trayCode) .streetId(orderInfo.getStreetId()) .direction(plcCmdInfo.getFromDirection()) .side(orderInfo.getSeparation()) + .code(tagStr) .row(orderInfo.getRow()) .column(orderInfo.getColumn()) .status(status) @@ -739,8 +722,9 @@ public class PlcService { stock.setExportTime(LocalDateTime.now()); stock.setCheckNum(plcCmdInfo.getOrderNum()); stock.setTrayCode(trayCode); + stock.setCode(tagStr); stock.setWmsTrayCode(wmsTrayCode); - stock.setCode(scanCode); +// stock.setCode(scanCode); stock.setWmsCode(wmsCode); stockMapper.updateById(stock); } @@ -751,16 +735,16 @@ public class PlcService { long end = System.currentTimeMillis(); long s = end - startTime; log.info("time:{}millisecond", s); - WebSocketVo webSocketVo = WebSocketVo.builder() - .message(plcCmdInfo) - .messageType("object") - .type("InventoryPush") - .build(); - try { - WebSocketServer.sendInfo(JSONObject.toJSONString(webSocketVo), ""); - } catch (IOException e) { - throw new RuntimeException(e); - } +// WebSocketVo webSocketVo = WebSocketVo.builder() +// .message(plcCmdInfo) +// .messageType("object") +// .type("InventoryPush") +// .build(); +// try { +// WebSocketServer.sendInfo(JSONObject.toJSONString(webSocketVo), ""); +// } catch (IOException e) { +// throw new RuntimeException(e); +// } return true; } @@ -794,39 +778,19 @@ public class PlcService { * @param plcCmdInfo 相关信息 * @param fromOrTo 确定方向 */ - public void RFIDCheck(PlcCmdInfo plcCmdInfo, boolean fromOrTo) { + public Set RFIDCheck(PlcCmdInfo plcCmdInfo, boolean fromOrTo) { log.info("开启rfid"); Street street = streetService.getStreetByPlcId(plcCmdInfo.getPlcId()); if (street != null) { //rfid不分左右,rfid使用同一ip和端口,依靠传递字符调整方向 RFID rfid = rfidService.getRFIDByPlc(street.getId(), null); if (rfid != null) { - if (fromOrTo) { - RFIDStart(rfid.getIp(), rfid.getPort(), street.getId(), plcCmdInfo.getFromDirection()); - } else - RFIDStart(rfid.getIp(), rfid.getPort(), street.getId(), plcCmdInfo.getToDirection()); - } - } - } - public void RFIDStart(String ip, Integer port, Integer streetId, Integer direction) { - RFIDSocket rfidSocket = new RFIDSocket(ip, port); - log.info("rfid调用,ip:" + ip + ";port:" + port); - rfidSocket.startCheck(direction,false); - RFIDMap.put(streetId, rfidSocket); - } + return checkTid(rfid.getIp(), rfid.getPort()); - public Set RFIDStop(PlcCmdInfo plcCmdInfo) { - Street street = streetService.getStreetByPlcId(plcCmdInfo.getPlcId()); - RFIDSocket rfidSocket = RFIDMap.get(street.getId()); - Set tags = null; - if (rfidSocket != null) { - tags = rfidSocket.getTags(); - log.info("tags:{}", tags); - rfidSocket.stopCheck(); - RFIDMap.remove(street.getId()); - } - return tags; + } + } + return new HashSet<>(); } diff --git a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDData.java b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDData.java new file mode 100644 index 0000000..633d9b7 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDData.java @@ -0,0 +1,19 @@ +package com.zhehekeji.web.service.RFID; + +import lombok.Data; + +@Data +public class RFIDData { + + private String pc; + private String epc; + private String crc; + private String tid; + + public RFIDData(String pc, String epc, String crc, String tid) { + this.pc = pc; + this.epc = epc; + this.crc = crc; + this.tid = tid; + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDMap.java b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDMap.java index dd50d5e..192adf9 100644 --- a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDMap.java +++ b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDMap.java @@ -5,18 +5,4 @@ import java.util.Map; public class RFIDMap { - private static Map socketMap = new HashMap<>(); - - - public static void put(Integer streetId,RFIDSocket rfidSocket){ - socketMap.put(streetId,rfidSocket); - } - - public static void remove(Integer streetId){ - socketMap.remove(streetId); - } - - public static RFIDSocket get(Integer streetId){ - return socketMap.get(streetId); - } } diff --git a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDReader.java b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDReader.java deleted file mode 100644 index 83812b5..0000000 --- a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDReader.java +++ /dev/null @@ -1,579 +0,0 @@ -package com.zhehekeji.web.service.RFID; - -import com.payne.reader.Reader; -import com.payne.reader.base.Consumer; -import com.payne.reader.bean.config.AntennaCount; -import com.payne.reader.bean.config.BaudRate; -import com.payne.reader.bean.config.Beeper; -import com.payne.reader.bean.config.ClearMaskId; -import com.payne.reader.bean.config.CmdStatus; -import com.payne.reader.bean.config.FastTidType; -import com.payne.reader.bean.config.GpioInType; -import com.payne.reader.bean.config.ProfileId; -import com.payne.reader.bean.receive.AntConnectionDetector; -import com.payne.reader.bean.receive.E710LinkProfile; -import com.payne.reader.bean.receive.Failure; -import com.payne.reader.bean.receive.FreqRegionResult; -import com.payne.reader.bean.receive.GpioOut; -import com.payne.reader.bean.receive.ImpinjFastTid; -import com.payne.reader.bean.receive.MaskInfo; -import com.payne.reader.bean.receive.MatchInfo; -import com.payne.reader.bean.receive.OperationTag; -import com.payne.reader.bean.receive.OutputPower; -import com.payne.reader.bean.receive.ReaderIdentifier; -import com.payne.reader.bean.receive.ReaderStatus; -import com.payne.reader.bean.receive.ReaderTemperature; -import com.payne.reader.bean.receive.ReceiveData; -import com.payne.reader.bean.receive.RfLinkProfile; -import com.payne.reader.bean.receive.RfPortReturnLoss; -import com.payne.reader.bean.receive.Success; -import com.payne.reader.bean.receive.TempLabel2; -import com.payne.reader.bean.receive.Version; -import com.payne.reader.bean.receive.WorkAntenna; -import com.payne.reader.bean.send.CustomSessionReadConfig; -import com.payne.reader.bean.send.FreqNormal; -import com.payne.reader.bean.send.FreqUserDefine; -import com.payne.reader.bean.send.Identifier; -import com.payne.reader.bean.send.InventoryConfig; -import com.payne.reader.bean.send.KillConfig; -import com.payne.reader.bean.send.LockConfig; -import com.payne.reader.bean.send.MaskConfig; -import com.payne.reader.bean.send.MatchConfig; -import com.payne.reader.bean.send.MultiAntReadTagConfig; -import com.payne.reader.bean.send.OutputPowerConfig; -import com.payne.reader.bean.send.ReadConfig; -import com.payne.reader.bean.send.TempLabel2Config; -import com.payne.reader.bean.send.WriteConfig; -import com.payne.reader.communication.ConnectHandle; -import com.payne.reader.communication.DataPacket; -import java.security.InvalidParameterException; -/** - * 读取器接口 - */ -public interface RFIDReader extends Reader { - /** - * 连接读取器 - * - * @param var1 连接处理回调 - * @return 连接是否成功 - */ - boolean connect(ConnectHandle var1); - - /** - * 连接读取器,并设置回调线程 - * - * @param var1 连接处理回调 - * @param var2 回调线程 - * @return 连接是否成功 - */ - boolean connect(ConnectHandle var1, boolean var2); - - /** - * 判断是否已连接 - * - * @return 是否已连接 - */ - boolean isConnected(); - - /** - * 断开连接 - */ - void disconnect(); - - /** - * 获取读取器地址 - * - * @return 读取器地址 - */ - byte getReaderAddress(); - - /** - * 获取天线数量 - * - * @return 天线数量 - */ - AntennaCount getAntennaCount(); - - /** - * 切换天线数量 - * - * @param var1 天线数量 - */ - void switchAntennaCount(AntennaCount var1); - - /** - * 设置命令超时时间 - * - * @param var1 超时时间 - */ - void setCmdTimeout(long var1); - - /** - * 重置读取器 - * - * @param var1 失败处理回调 - */ - void reset(Consumer var1); - - /** - * 设置波特率 - * - * @param var1 波特率类型 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setBaudRate(BaudRate var1, Consumer var2, Consumer var3); - - /** - * 设置波特率 - * - * @param var1 波特率类型 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - * @param var4 异常处理回调 - */ - void setBaudRate(BaudRate var1, Consumer var2, Consumer var3, Consumer var4); - - /** - * 设置读取器地址 - * - * @param var1 读取器地址 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setReaderAddress(byte var1, Consumer var2, Consumer var3); - - /** - * 获取固件版本 - * - * @param var1 版本获取成功处理回调 - * @param var2 失败处理回调 - */ - void getFirmwareVersion(Consumer var1, Consumer var2); - - /** - * 设置蜂鸣器模式 - * - * @param var1 蜂鸣器模式 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setBeeperMode(Beeper var1, Consumer var2, Consumer var3); - - /** - * 获取读取器温度 - * - * @param var1 读取器温度获取成功处理回调 - * @param var2 失败处理回调 - */ - void getReaderTemperature(Consumer var1, Consumer var2); - - /** - * 读取GPIO输出 - * - * @param var1 GPIO输出获取成功处理回调 - * @param var2 失败处理回调 - */ - void readGpio(Consumer var1, Consumer var2); - - /** - * 写入GPIO输入 - * - * @param var1 GPIO输入类型 - * @param var2 输入值 - * @param var3 成功处理回调 - * @param var4 失败处理回调 - */ - void writeGpio(GpioInType var1, boolean var2, Consumer var3, Consumer var4); - - /** - * 设置天线连接探测器地址 - * - * @param var1 探测器地址 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setAntConnectionDetector(byte var1, Consumer var2, Consumer var3); - - /** - * 获取天线连接探测器地址 - * - * @param var1 探测器地址获取成功处理回调 - * @param var2 失败处理回调 - */ - void getAntConnectionDetector(Consumer var1, Consumer var2); - - /** - * 设置工作天线 - * - * @param var1 工作天线 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - * @throws InvalidParameterException 参数无效异常 - */ - void setWorkAntenna(int var1, Consumer var2, Consumer var3) throws InvalidParameterException; - - /** - * 获取工作天线 - * - * @param var1 工作天线获取成功处理回调 - * @param var2 失败处理回调 - */ - void getWorkAntenna(Consumer var1, Consumer var2); - - /** - * 获取缓存工作天线 - * - * @return 缓存工作天线 - */ - int getCacheWorkAntenna(); - - /** - * 获取缓存天线组 - * - * @return 缓存天线组 - */ - int getCacheAntennaGroup(); - - /** - * 设置输出功率 - * - * @param var1 输出功率配置 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - * @throws InvalidParameterException 参数无效异常 - */ - void setOutputPower(OutputPowerConfig var1, Consumer var2, Consumer var3) throws InvalidParameterException; - - /** - * 获取输出功率 - * - * @param var1 输出功率获取成功处理回调 - * @param var2 失败处理回调 - */ - void getOutputPower(Consumer var1, Consumer var2); - - /** - * 设置均匀输出功率 - * - * @param var1 均匀输出功率 - * @param var2 设置成功处理回调 - * @param var3 失败处理回调 - */ - void setOutputPowerUniformly(byte var1, boolean var2, Consumer var3, Consumer var4); - - /** - * 设置频率区域 - * - * @param var1 频率区域类型 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setFrequencyRegion(FreqNormal var1, Consumer var2, Consumer var3); - - /** - * 设置用户定义频率 - * - * @param var1 用户定义频率类型 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setUserDefineFrequency(FreqUserDefine var1, Consumer var2, Consumer var3); - - /** - * 获取频率区域 - * - * @param var1 频率区域获取成功处理回调 - * @param var2 失败处理回调 - */ - void getFrequencyRegion(Consumer var1, Consumer var2); - - /** - * 设置读取器标识 - * - * @param var1 读取器标识 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setReaderIdentifier(Identifier var1, Consumer var2, Consumer var3); - - /** - * 获取读取器标识 - * - * @param var1 读取器标识获取成功处理回调 - * @param var2 失败处理回调 - */ - void getReaderIdentifier(Consumer var1, Consumer var2); - - /** - * 设置RF链接配置 - * - * @param var1 链接配置 - * @param var2 成功处理回调 - * @param var3 失败处理回调 - */ - void setRfLinkProfile(ProfileId var1, Consumer var2, Consumer var3); - - /** - * 获取RF链接配置 - * - * @param var1 RF链接配置获取成功处理回调 - * @param var2 失败处理回调 - */ - void getRfLinkProfile(Consumer var1, Consumer var2); - - /** - * 设置E710链接配置 - * - * @param var1 链接配置 - * @param var2 配置类型 - * @param var3 成功处理回调 - * @param var4 失败处理回调 - */ - void setE710LinkProfile(ProfileId var1, byte var2, Consumer var3, Consumer var4); - - /** - * 获取E710链接配置 - * - * @param var1 E710链接配置获取成功处理回调 - * @param var2 失败处理回调 - */ - void getE710LinkProfile(Consumer var1, Consumer var2); - - /** - * 获取RF端口返回损耗 - * - * @param var1 端口号 - * @param var2 返回损耗获取成功处理回调 - * @param var3 失败处理回调 - */ - void getRfPortReturnLoss(byte var1, Consumer var2, Consumer var3); - - /** - * 设置库存配置 - * - * @param var1 库存配置 - * @throws InvalidParameterException 参数无效异常 - */ - void setInventoryConfig(InventoryConfig var1) throws InvalidParameterException; - - /** - * 开始库存盘点 - * - * @param var1 是否开启多天线读取 - */ - void startInventory(boolean var1); - - /** - * 停止盘点。 - */ - void stopInventory(); - - /** - * 停止盘点,参数为一个布尔值。 - * - * @param var1 布尔值参数 - */ - void stopInventory(boolean var1); - - /** - * 设置MultiAntReadTagConfig配置。 - * - * @param var1 MultiAntReadTagConfig对象 - */ - void setMultiAntReadTagConfig(MultiAntReadTagConfig var1); - - /** - * 启动MultiAntReadTag。 - */ - void startMultiAntReadTag(); - - /** - * 停止MultiAntReadTag。 - */ - void stopMultiAntReadTag(); - - /** - * 读取标签。 - * - * @param var1 读取配置ReadConfig对象 - * @param var2 操作标签回调函数 - * @param var3 失败回调函数 - */ - void readTag(ReadConfig var1, Consumer var2, Consumer var3); - - /** - * 读取标签。 - * - * @param var1 自定义会话读取配置CustomSessionReadConfig对象 - * @param var2 操作标签回调函数 - * @param var3 失败回调函数 - */ - void readTag(CustomSessionReadConfig var1, Consumer var2, Consumer var3); - - /** - * 写入标签。 - * - * @param var1 写入配置WriteConfig对象 - * @param var2 布尔值参数 - * @param var3 操作标签回调函数 - * @param var4 失败回调函数 - */ - void writeTag(WriteConfig var1, boolean var2, Consumer var3, Consumer var4); - - /** - * 锁定标签。 - * - * @param var1 锁定配置LockConfig对象 - * @param var2 操作标签回调函数 - * @param var3 失败回调函数 - */ - void lockTag(LockConfig var1, Consumer var2, Consumer var3); - - /** - * 杀死标签。 - * - * @param var1 杀死配置KillConfig对象 - * @param var2 操作标签回调函数 - * @param var3 失败回调函数 - */ - void killTag(KillConfig var1, Consumer var2, Consumer var3); - - /** - * 设置ImpinjFastTid。 - * - * @param var1 FastTidType对象 - * @param var2 布尔值参数 - * @param var3 成功回调函数 - * @param var4 失败回调函数 - */ - void setImpinjFastTid(FastTidType var1, boolean var2, Consumer var3, Consumer var4); - - /** - * 获取ImpinjFastTid。 - * - * @param var1 成功回调函数 - * @param var2 失败回调函数 - */ - void getImpinjFastTid(Consumer var1, Consumer var2); - - /** - * 设置EpcMatch。 - * - * @param var1 匹配配置MatchConfig对象 - * @param var2 成功回调函数 - * @param var3 失败回调函数 - */ - void setEpcMatch(MatchConfig var1, Consumer var2, Consumer var3); - - /** - * 获取EpcMatch。 - * - * @param var1 成功回调函数 - * @param var2 失败回调函数 - */ - void getEpcMatch(Consumer var1, Consumer var2); - - /** - * 清除EpcMatch。 - * - * @param var1 成功回调函数 - * @param var2 失败回调函数 - */ - void clearEpcMatch(Consumer var1, Consumer var2); - - /** - * 设置TagMask。 - * - * @param var1 掩码配置MaskConfig对象 - * @param var2 成功回调函数 - * @param var3 失败回调函数 - */ - void setTagMask(MaskConfig var1, Consumer var2, Consumer var3); - - /** - * 获取TagMask。 - * - * @param var1 成功回调函数 - * @param var2 失败回调函数 - */ - void getTagMask(Consumer var1, Consumer var2); - - /** - * 清除TagMask。 - * - * @param var1 清除的TagMaskID - * @param var2 成功回调函数 - * @param var3 失败回调函数 - */ - void clearTagMask(ClearMaskId var1, Consumer var2, Consumer var3); - - /** - * 设置ReaderStatus。 - * - * @param var1 字节参数 - * @param var2 成功回调函数 - * @param var3 失败回调函数 - */ - void setReaderStatus(byte var1, Consumer var2, Consumer var3); - - /** - * 获取ReaderStatus。 - * - * @param var1 成功回调函数 - * @param var2 失败回调函数 - */ - void getReaderStatus(Consumer var1, Consumer var2); - - /** - * 获取TempLabel2。 - * - * @param var1 TempLabel2对象 - * @param var2 失败回调函数 - */ - void measTempLabel2(TempLabel2Config var1, Consumer var2, Consumer var3); - - /** - * 设置CommandStatusCallback。 - * - * @param var1 回调函数 - */ - void setCommandStatusCallback(Consumer var1); - - /** - * 设置OriginalDataCallback。 - * - * @param var1 原始数据回调函数 - * @param var2 失败回调函数 - */ - void setOriginalDataCallback(Consumer var1, Consumer var2); - - /** - * 设置UndefinedResultCallback。 - * - * @param var1 未定义结果回调函数 - */ - void setUndefinedResultCallback(Consumer var1); - - /** - * @deprecated 已过时,请勿使用 - */ - @Deprecated - void sendCustomRequest(byte var1, byte[] var2); - - /** - * 发送自定义请求。 - * - * @param var1 数据包对象 - */ - void sendCustomRequest(DataPacket var1); - - /** - * 获取SdkBuildInfo。 - * - * @return SdkBuildInfo信息 - */ - default String getSdkBuildInfo() { - return "add cmd:89, packaged at 2022-10-13 04.00"; - } -} \ No newline at end of file diff --git a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocket.java b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocket.java deleted file mode 100644 index 6412465..0000000 --- a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocket.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.zhehekeji.web.service.RFID; - -import com.payne.connect.net.NetworkHandle; -import com.payne.reader.Reader; -import com.payne.reader.base.Consumer; -import com.payne.reader.bean.config.AntennaCount; -import com.payne.reader.bean.receive.*; -import com.payne.reader.bean.send.FastSwitchFourAntennaInventory; -import com.payne.reader.bean.send.InventoryConfig; -import com.payne.reader.process.ReaderImpl; -import com.payne.reader.util.ArrayUtils; - -import com.zhehekeji.web.util.ToolUtil; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -public class RFIDSocket { - private String ip; - private int port; - private boolean running; - Reader mReader; - - private Set tags = new HashSet<>(); - - private Map tagsCount = new ConcurrentHashMap<>(); - - public static void main(String[] args) { - String tagStr = "363000145224505289907900"; - if(tagStr.startsWith("363000") &&tagStr.endsWith("00")){ - tagStr = tagStr.substring(0, tagStr.length() - 2); - } - System.out.println(tagStr); - } - public Set getTags() { - return tags; - } - public RFIDSocket(String ip, Integer port) { - this.ip = ip; - this.port = port; - - NetworkHandle handle = new NetworkHandle(ip, (port)); - mReader = ReaderImpl.create(AntennaCount.FOUR_CHANNELS); - - boolean linkSuccess =false; - try { - linkSuccess = mReader.connect(handle); - - }catch (Exception e) { - e.printStackTrace(); - } - if (linkSuccess) { - System.out.println("reader1 connect success"); - } else { - throw new RuntimeException("reader1 connect fail"); - } - - } - - /**识别 - * - * @param direction 左右 - * @param foreach 是否循环切换天线 - */ - public void startCheck(Integer direction,boolean foreach) { -// Reader mReader = ReaderImpl.create(AntennaCount.SIXTEEN_CHANNELS); -// Reader mReader = ReaderImpl.create(AntennaCount.EIGHT_CHANNELS); - running = true; - Thread thread = new Thread(new Runnable() { - public void run() { - mReader.setOriginalDataCallback( - new Consumer() { - @Override - public void accept(byte[] onSend) throws Exception { - //System.out.println("---reader 1 send :" + ArrayUtils.bytesToHexString(onSend, 0, onSend.length)); - } - }, - new Consumer() { - @Override - public void accept(byte[] onReceive) throws Exception { - - - } - }); - FastSwitchFourAntennaInventory inventory = new FastSwitchFourAntennaInventory.Builder().build(); - InventoryConfig config = new InventoryConfig.Builder() - .setInventory(inventory) - .setOnInventoryTagSuccess(new Consumer() { - - @Override - public void accept(InventoryTag tag) throws Exception { - System.out.println("reader1 inventory tag :" + tag.getEpc()); - String tagStr = tag.getEpc().replace(" ",""); - tagStr = tagStr.substring(tagStr.length() - 8); - tags.add(tagStr); - if (ToolUtil.isNotEmpty(tagsCount.get(tagStr))) { - tagsCount.put(tagStr, tagsCount.get(tagStr) + 1); - } else { - tagsCount.put(tagStr, 1); - } - } - }) - .setOnInventoryTagEndSuccess(new Consumer() { - - @Override - public void accept(InventoryTagEnd arg0) throws Exception { -// System.out.println("reader1 InventoryTagEnd"); - } - }) - .setOnFailure(new Consumer() { - - @Override - public void accept(InventoryFailure failure) throws Exception { - System.out.println("reader1 inventory fail :" + (failure.getErrorCode() & 0xFF)); - } - }) - .build(); - mReader.setInventoryConfig(config); - mReader.startInventory(true); - - mReader.setWorkAntenna(direction, - new Consumer() { - @Override - public void accept(Success success) throws Exception { - //切换天线 - //处理成功 - } - }, new Consumer() { - @Override - public void accept(Failure failure) throws Exception { - //处理失败情况 - } - } - ); - byte[] bytes = new byte[1]; - bytes[0] = 0x01; - while (running) { - try { - bytes[0] = (byte) (bytes[0] == 0x01 ? 0x00 : 0x01); - Thread.sleep(1000); - if(foreach){ - mReader.setWorkAntenna(bytes[0],(v)->{ - System.out.println("reader1 setWorkAntenna success"); - },(v)->{ - System.out.println("reader1 setWorkAntenna fail"); - }); - } - } catch (Exception e) { - e.printStackTrace(); - stopCheck(); - } - } - } - - }); - thread.start(); - - } - - public void stopCheck() { - running = false; - System.out.println("reader1 stop"); - if (mReader != null) { - mReader.stopInventory(); - mReader.disconnect(); - } - - } - - public String getTag() { - if (ToolUtil.isNotEmpty(tagsCount)) { - int i = 0; - String tag = ""; - for (String t : tagsCount.keySet()) { - if (i < tagsCount.get(t)) { - tag = t; - i = tagsCount.get(t); - } - } - return tag; - } - return ""; - } - - -} diff --git a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocketOld.java b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocketOld.java index b623de8..e69de29 100644 --- a/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocketOld.java +++ b/web/src/main/java/com/zhehekeji/web/service/RFID/RFIDSocketOld.java @@ -1,162 +0,0 @@ -package com.zhehekeji.web.service.RFID; - -import com.module.interaction.RXTXListener; -import com.module.interaction.ReaderHelper; -import com.rfid.RFIDReaderHelper; -import com.rfid.ReaderConnector; -import com.rfid.rxobserver.RXObserver; -import com.rfid.rxobserver.bean.RXInventoryTag; - -import com.rfid.bean.MessageTran; -import com.util.StringTool; -import com.zhehekeji.web.util.ToolUtil; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -public class RFIDSocketOld { - private String ip; - private int port; - private ReaderHelper mReaderHelper; - private ReaderConnector mReaderConnector; - private boolean running; - - private Set tags = new HashSet<>(); - - private Map tagsCount = new ConcurrentHashMap<>(); - public Set getTags(){ - return tags; - } - - - private Observer mObserver = new RXObserver() { - @Override - protected void onInventoryTag(RXInventoryTag tag) { - System.out.println("EPC data:" + tag.strEPC); - } - - @Override - protected void onInventoryTagEnd(RXInventoryTag.RXInventoryTagEnd endTag) { - System.out.println("inventory end:" + endTag.mTotalRead); - ((RFIDReaderHelper) mReaderHelper).realTimeInventory((byte) 0xff,(byte)0x01); - } - - @Override - protected void onExeCMDStatus(byte cmd,byte status) { - System.out.format("CDM:%s Execute status:%S\n", - String.format("%02X",cmd),String.format("%02x", status)); - } - }; - private RXTXListener mListener = new RXTXListener() { - @Override - //获取接收器返回的数据 - public void reciveData(byte[] btAryReceiveData) { - // TODO Auto-generated method stub - System.out.println("reciveData: " + StringTool.byteArrayToString(btAryReceiveData, 0, btAryReceiveData.length)); - MessageTran messageTran = new MessageTran(btAryReceiveData); - if (messageTran != null){ - System.out.println("ary data length: " + messageTran.getAryData().length); - System.out.println("artData: " + StringTool.byteArrayToString(messageTran.getAryData(), 0, messageTran.getAryData().length)); - StringBuffer sb = new StringBuffer(); - int aryDataLength = messageTran.getAryData().length; - if (aryDataLength > 8){ - for (int i = 0; i < aryDataLength; ++i){ - sb.append(java.lang.String.format("%02X",messageTran.getAryData()[i])); - } - - String tag = sb.toString(); - //int index = st.indexOf("E"); - //String tag = st.substring(index, index+16); - System.out.println("tag: "+tag); - tags.add(tag); - if(ToolUtil.isNotEmpty(tagsCount.get(tag))){ - tagsCount.put(tag, tagsCount.get(tag)+1); - }else{ - tagsCount.put(tag, 1); - } - } - } - } - - @Override - public void sendData(byte[] btArySendData) { - // TODO Auto-generated method stub - System.out.println("sendData: " + StringTool.byteArrayToString(btArySendData, 0, btArySendData.length)); - } - - @Override - public void onLostConnect() { - // TODO Auto-generated method stub - } - - }; - public RFIDSocketOld(String ip, Integer port){ - mReaderConnector = new ReaderConnector(); - mReaderHelper = mReaderConnector.connectNet(ip, port); - } - public void startCheck(Integer direction){ - running = true; - Thread thread = new Thread(new Runnable() { - public void run() { - - if (mReaderHelper != null) { - System.out.println("Connect success!"); - try { - mReaderHelper.registerObserver(mObserver); - mReaderHelper.setRXTXListener(mListener); - - Thread.sleep(500); - //start to find the tags -// ((RFIDReaderHelper) mReaderHelper).realTimeInventory((byte) 0xff,(byte)0x01); - while (true) { -// if (i%2==0){ - if (!running){ - break; - } - if (direction == 1) { - //切换天线 0x00:天线1;0x01:天线2 - ((RFIDReaderHelper) mReaderHelper).setWorkAntenna((byte) 0xFF, (byte) 0x00); - } else { - ((RFIDReaderHelper) mReaderHelper).setWorkAntenna((byte) 0xFF, (byte) 0x01); - } - //开始盘存180006B - //((RFIDReaderHelper) mReaderHelper).iso180006BInventory((byte) 0xFF); - ((RFIDReaderHelper) mReaderHelper).inventory((byte) 0xFF, (byte) 0x0A); -// i++; - Thread.sleep(70); - } - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } else { - System.out.println("Connect faild!"); - mReaderConnector.disConnect(); - } - } - }); - thread.start(); - } - - public void stopCheck(){ - running = false; - if (mReaderConnector.isConnected()){ - mReaderConnector.disConnect(); - } - } - public String getTag(){ - if(ToolUtil.isNotEmpty(tagsCount)){ - int i = 0; - String tag = "" ; - for (String t : tagsCount.keySet()){ - if (i receiveRFIDData() throws IOException { + Set dataSet = new HashSet<>(); + + // 创建一个缓冲区来存储接收到的数据 + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + // 设置一个超时机制,避免无限等待 + // 先读取一批数据到缓冲区 + byte[] tempBuffer = new byte[1024]; + + + try { + int bytesRead; + while ((bytesRead = inputStream.read(tempBuffer)) != -1) { + buffer.write(tempBuffer, 0, bytesRead); // 记录读取的数据到日志 + log.info("读取到 {} 字节数据: {}", bytesRead, bytesToHex(Arrays.copyOfRange(tempBuffer, 0, bytesRead))); + + // 如果读取到足够数据就停止 + if (buffer.size() > 4096) { + break; + } + } + log.info("总共读取到 {} 字节数据", buffer.size()); + } catch (SocketTimeoutException e) { + // 超时正常,继续处理已接收的数据 + log.info("读取数据超时,继续处理已接收的数据"); + } + + // 处理缓冲区中的数据 + byte[] receivedData = buffer.toByteArray(); + int position = 0; + + // 循环查找并解析所有以A0开头的数据包 + while (position < receivedData.length - 2) { + // 查找A0起始字节 + if (receivedData[position] == (byte) 0xA0) { + // 确保有足够的数据读取长度字节 + if (position + 1 >= receivedData.length) { + break; + } + + // 读取长度 + int length = receivedData[position + 1] & 0xFF; + + // 确保有足够的数据 + if (position + 2 + length > receivedData.length) { + break; + } + + // 提取数据部分 + byte[] data = Arrays.copyOfRange(receivedData, position + 2, position + 2 + length); + + // 解析数据 + RFIDData rfidData = parseRFIDData(data); + if (rfidData != null) { + dataSet.add(rfidData); + } + + // 移动到下一个数据包 + position += 2 + length; + } else { + // 移动到下一个字节 + position++; + } + } + + return dataSet; + } + private RFIDData parseRFIDData(byte[] data) { + try { + // 检查数据长度是否足够 + if (data.length < 21) { // 至少需要21个字节 + return null; + } + + // 检查固定值是否正确 + if((data[1] & 0xFF) != 0X81){ + return null; + } + + // 0x01 是固定值 (data[0]) + // 81 00 0C 1C 是其他数据 (data[1]-data[4]) + // 接下来2个字节是PC值 (data[5], data[6]) + String pc = bytesToHex(Arrays.copyOfRange(data, 5, 7)); + + // 接下来12个字节是EPC值 (data[7] 到 data[18]) + String epc = bytesToHex(Arrays.copyOfRange(data, 7, 19)); + + // 接下来2个字节是CRC值 (data[19], data[20]) + String crc = bytesToHex(Arrays.copyOfRange(data, 19, 21)); + + // 剩余字节是TID值 (data[21] 到 data[33],共12个字节) + // 确保不会越界 + int tidStart = 21; + int tidEnd = tidStart + 12; // TID固定为12个字节 + if (tidEnd <= data.length) { + String tid = bytesToHex(Arrays.copyOfRange(data, tidStart, tidEnd)); + RFIDData rfidData = new RFIDData(pc, epc, crc, tid); + log.info("rfidData:{}", rfidData); + return rfidData; + } + + // 如果没有TID数据,创建一个空的TID + RFIDData rfidData = new RFIDData(pc, epc, crc, ""); + log.info("rfidData:{}", rfidData); + return rfidData; + } catch (Exception e) { + log.error("解析RFID数据时出错: ", e); + return null; + } + } + + private byte[] hexStringToByteArray(String hex) { + hex = hex.replaceAll(" ", ""); // 移除空格 + int len = hex.length(); + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + + Character.digit(hex.charAt(i+1), 16)); + } + return data; + } + + private String bytesToHex(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02X", b)); + } + return sb.toString(); + } + + public static Set checkTid(String ip ,int port){ + RFIDTCPClient client = new RFIDTCPClient(ip, port); + + Set data = new HashSet<>(); + if (client.connect()) { + try { + for (int i = 0; i < 8; i++){ + if (i%2==0) + client.sendHexCommand("A0 04 01 74 01 E6"); + else + client.sendHexCommand("A0 04 01 74 00 E7"); + + client.sendHexCommand("A0 0A FF 81 02 00 06 00 00 00 00 CE"); + + data.addAll(client.receiveRFIDData()); + } + if (data != null) { + log.info("接收到RFID数据: " + data.toString()); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + client.disconnect(); + } + } else { + System.out.println("连接失败"); + } + Set setData = data.stream().map(RFIDData::getTid).collect(Collectors.toSet()); + log.info("接收到的RFID数据: " + setData); + return setData; + } + public static void main(String[] args) { + checkTid("127.0.0.1", 4002); + } +} diff --git a/web/src/main/java/com/zhehekeji/web/service/impl/RfidLiveServiceImpl.java b/web/src/main/java/com/zhehekeji/web/service/impl/RfidLiveServiceImpl.java index f6e0993..9687a7a 100644 --- a/web/src/main/java/com/zhehekeji/web/service/impl/RfidLiveServiceImpl.java +++ b/web/src/main/java/com/zhehekeji/web/service/impl/RfidLiveServiceImpl.java @@ -47,26 +47,6 @@ public class RfidLiveServiceImpl extends ServiceImpl i @Override public void rfidOrderStock(PlcCmdInfo plcCmdInfo, Integer times, String trayCode) { - Street street = streetService.getStreetByPlcId(plcCmdInfo.getPlcId()); - RFID rfid = rfidMapper.selectOne(new QueryWrapper().eq("street_id", street.getId())); - String tags = ""; - if (times == 3) { - plcService.RFIDCheck(plcCmdInfo, false); - try { - Thread.sleep(1000 * configProperties.getRfid().getScanTime()); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } finally { - tags = String.join(",", plcService.RFIDStop(plcCmdInfo)); - log.info("随行rfid扫描结果:"+tags); - } - rfidRemoveLive(plcCmdInfo,street,rfid); - rfidSave( plcCmdInfo,tags,street,rfid); - } - //取货完成删除live - if (times == 2) { - rfidRemoveLive(plcCmdInfo,street,rfid); - } } diff --git a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java index 98f532e..aa79350 100644 --- a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java +++ b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecDecoder.java @@ -201,7 +201,7 @@ public class KsecDecoder extends DelimiterBasedFrameDecoder { //rfid的逻辑 String code = dataInfo.getCmdName(); log.info("盘点指令:{}", ksecInfo); - plcService.check(plcCmdInfo,ksecInfo.getType(),dataInfo.getCode(),dataInfo.getTrayCode()); + plcService.check(plcCmdInfo,ksecInfo.getType(),dataInfo.getLotnum(),dataInfo.getLotnum()); ksecInfo.getData().setAckStatus(1); ctx.channel().writeAndFlush(ksecInfo); diff --git a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecNettyClient.java b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecNettyClient.java index 859d8ba..8681bfe 100644 --- a/web/src/main/java/com/zhehekeji/web/service/ksec/KsecNettyClient.java +++ b/web/src/main/java/com/zhehekeji/web/service/ksec/KsecNettyClient.java @@ -6,6 +6,8 @@ import com.zhehekeji.web.config.ConfigProperties; import com.zhehekeji.web.service.PlcService; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; @@ -13,88 +15,238 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReentrantLock; @Slf4j @Component public class KsecNettyClient { - private static EventLoopGroup group = new NioEventLoopGroup(); @Resource private PlcService plcService; @Resource private ConfigProperties configProperties; - private static Channel channel; + private EventLoopGroup group; + private volatile Channel channel; + private final AtomicBoolean isConnecting = new AtomicBoolean(false); + private final AtomicBoolean isConnected = new AtomicBoolean(false); + private final ReentrantLock connectionLock = new ReentrantLock(); + // 连接配置参数 + private static final int CONNECT_TIMEOUT = 5000; // 连接超时时间(毫秒) + private static final long INITIAL_RECONNECT_DELAY = 1000; // 初始重连延迟(毫秒) + private static final long MAX_RECONNECT_DELAY = 30000; // 最大重连延迟(毫秒) + private static final long RECONNECT_DELAY_MULTIPLIER = 2; // 重连延迟倍数 + + @PostConstruct + public void init() { + group = new NioEventLoopGroup(); + log.info("KsecNettyClient 初始化完成"); + // 启动后立即尝试连接 + reconnect(1); + } + + /** + * 创建客户端连接 + * @param ksec KSEC配置信息 + * @throws InterruptedException 如果连接过程中被中断 + */ public void createClient(ConfigProperties.KSEC ksec) throws InterruptedException { - String lotnum = FileUtil.getText("lastLotnum"); - if(lotnum != null){ - KsecDecoder.setLastLotnum(lotnum); + if (isConnecting.get()) { + log.warn("连接已在进行中,跳过重复连接请求"); + return; } - if (StringUtils.isEmpty(ksec.getIp()) || ksec.getPort() == null) { + + if (!isConnecting.compareAndSet(false, true)) { + log.warn("无法设置连接状态,可能有其他线程正在连接"); return; } - Bootstrap client = new Bootstrap(); - client.group(group); - client.channel(NioSocketChannel.class); - KsecInfo heart = KsecInfo.heart(); - client.handler(new KescFilter(heart, plcService,this)); - // 连接服务端 - - channel = client.connect(ksec.getIp(), ksec.getPort()).sync().channel(); + + try { + // 清理旧连接 + closeChannel(); + + String lotnum = FileUtil.getText("lastLotnum"); + if (lotnum != null) { + KsecDecoder.setLastLotnum(lotnum); + } + + if (StringUtils.isEmpty(ksec.getIp()) || ksec.getPort() == null) { + log.error("无效的连接参数: IP={}, Port={}", ksec.getIp(), ksec.getPort()); + throw new IllegalArgumentException("无效的连接参数"); + } + + Bootstrap client = new Bootstrap(); + client.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT) + .option(ChannelOption.SO_KEEPALIVE, true) + .option(ChannelOption.TCP_NODELAY, true); + + KsecInfo heart = KsecInfo.heart(); + client.handler(new KescFilter(heart, plcService, this)); + + log.info("开始连接到PLC服务器: {}:{}", ksec.getIp(), ksec.getPort()); + + // 异步连接并等待结果 + ChannelFuture future = client.connect(ksec.getIp(), ksec.getPort()).await(); + + if (future.isSuccess()) { + channel = future.channel(); + isConnected.set(true); + log.info("成功连接到PLC服务器: {}:{}", ksec.getIp(), ksec.getPort()); + } else { + isConnected.set(false); + throw new RuntimeException("连接到PLC服务器失败", future.cause()); + } + } finally { + isConnecting.set(false); + } } /** - * 断线重连 尝试 RECONNECT_NUM 次 - * - * @param upId + * 断线重连机制 - 无限重连 + * @param upId 上位机ID */ public void reconnect(Integer upId) { - Boolean isConnected = false; - int num = 0; - ConfigProperties.KSEC ksec = configProperties.getKsec(); - if (ksec == null) { - log.error("reconnect ,upPc is null ,id:{}", upId); + // 使用锁确保同一时间只有一个重连线程在运行 + if (!connectionLock.tryLock()) { + log.debug("重连线程已在运行,跳过重复的重连请求"); return; } + try { - Thread.sleep(1500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - while ((ksec.getReconnectNum() == -1 || num < ksec.getReconnectNum() ) && !isConnected) { + ConfigProperties.KSEC ksec = configProperties.getKsec(); + if (ksec == null) { + log.error("重连失败,KSEC配置为空, upId: {}", upId); + // 即使配置为空也继续尝试重连 + scheduleReconnect(upId, INITIAL_RECONNECT_DELAY); + return; + } + + // 检查是否已经连接 + if (isConnected() && channel != null && channel.isActive()) { + log.info("连接仍然有效,无需重连"); + return; + } + try { + log.info("尝试连接到PLC服务器 {}:{}", ksec.getIp(), ksec.getPort()); createClient(ksec); + log.info("连接PLC服务器成功"); + } catch (Exception e) { + log.error("连接PLC服务器失败: {}", e.getMessage(), e); + // 连接失败,安排下次重连 + scheduleReconnect(upId, INITIAL_RECONNECT_DELAY); + } + } finally { + connectionLock.unlock(); + } + } + + /** + * 安排下次重连 + * @param upId 上位机ID + * @param delay 延迟时间(毫秒) + */ + private void scheduleReconnect(Integer upId, long delay) { + // 确保延迟不超过最大值 + long actualDelay = Math.min(delay, MAX_RECONNECT_DELAY); + + log.info("计划在 {} ms 后进行重连尝试", actualDelay); + + // 在事件循环组中安排重连任务 + group.schedule(() -> { + try { + reconnect(upId); } catch (Exception e) { - //没连上 继续 - log.error("reconnect error num:{}", num); - if(channel!= null) - channel.close(); - num++; - try { - Thread.sleep(ksec.getReconnectInterval()*1000); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); + log.error("调度重连任务时发生异常: {}", e.getMessage(), e); + } + }, actualDelay, TimeUnit.MILLISECONDS); + } + + /** + * 检查连接状态 + * @return true表示已连接且活跃,false表示未连接或连接已断开 + */ + public boolean isConnected() { + return isConnected.get() && channel != null && channel.isActive(); + } + + /** + * 关闭当前连接 + */ + public void closeChannel() { + if (channel != null) { + try { + if (channel.isOpen()) { + channel.close().awaitUninterruptibly(); + log.info("PLC连接已关闭"); } - continue; + } catch (Exception e) { + log.warn("关闭PLC连接时发生异常: {}", e.getMessage()); + } finally { + channel = null; + isConnected.set(false); } - isConnected = true; } - if (isConnected) { - log.info("plc reconnect success"); + } + + /** + * 发送数据到PLC + * @param ksecInfo 要发送的数据 + */ + public void write(KsecInfo ksecInfo) { + if (isConnected()) { + try { + channel.writeAndFlush(ksecInfo).addListener(future -> { + if (!future.isSuccess()) { + log.error("发送数据到PLC失败: {}", future.cause().getMessage(), future.cause()); + // 发送失败可能意味着连接已断开,触发重连 + handleConnectionLost(); + } + }); + log.debug("已发送数据到PLC服务器: {}", ksecInfo); + } catch (Exception e) { + log.error("发送数据时发生异常: {}", e.getMessage(), e); + handleConnectionLost(); + } } else { - log.error("plc reconnect error .upPcId:{},reconnect num:{},ip:{},port:{}", upId, num, ksec.getIp(), ksec.getPort()); + log.error("无法发送数据,PLC未连接"); + handleConnectionLost(); } } - public static void write(KsecInfo ksecInfo){ - if(channel != null){ - log.info("write server:"+ksecInfo); - channel.writeAndFlush(ksecInfo); - }else { - log.error(" no connected upPc"); + /** + * 处理连接丢失事件 + */ + private void handleConnectionLost() { + if (isConnected.compareAndSet(true, false)) { + log.error("检测到PLC连接丢失"); + closeChannel(); + // 触发重连 + reconnect(1); } + } + /** + * 销毁资源 + */ + @PreDestroy + public void destroy() { + try { + closeChannel(); + if (group != null) { + group.shutdownGracefully().awaitUninterruptibly(); + log.info("Netty事件循环组已关闭"); + } + } catch (Exception e) { + log.error("关闭KsecNettyClient时发生异常: {}", e.getMessage(), e); + } } }