|
@@ -0,0 +1,422 @@
|
|
|
+package com.jiayue.ipfcst.fileupload.IEC102;
|
|
|
+
|
|
|
+import cn.hutool.core.map.MapUtil;
|
|
|
+import cn.hutool.core.util.ArrayUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.ElectricField;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.UploadFileChannel;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.UploadFileLog;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.UploadObject;
|
|
|
+import com.jiayue.ipfcst.fileupload.dto.Validate102Dto;
|
|
|
+import com.jiayue.ipfcst.fileupload.util.FileConstant;
|
|
|
+import com.jiayue.ipfcst.fileupload.util.FileMutableInteger;
|
|
|
+import com.jiayue.ipfcst.fileupload.util.FileUtil;
|
|
|
+import io.netty.channel.ChannelHandlerContext;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Propagation;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Iterator;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 102内蒙服务端业务处理类
|
|
|
+ *
|
|
|
+ * @author xsl
|
|
|
+ * @version 3.0
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class ServerFor102NMService extends Base102Service {
|
|
|
+ @Transactional(propagation = Propagation.REQUIRED)
|
|
|
+ public String handlerMessage(String receiveMessage, UploadObject uploadObject, UploadFileChannel uploadFileChannel, ElectricField electricField, Logger log, ChannelHandlerContext ctx) {
|
|
|
+ String[] rmArray = IEC102Uitl.stingToArray(receiveMessage);
|
|
|
+ String sendMessage = "";
|
|
|
+ String sendCtrlChinese = "";
|
|
|
+ String receiveCtrlChinese = "";
|
|
|
+
|
|
|
+ if (FileConstant.validateMessage.get(uploadFileChannel.getId()+"")!=null){
|
|
|
+ // 需要校验接收的帧是否正确
|
|
|
+ Validate102Dto validate102Dto = FileConstant.validateMessage.get(uploadFileChannel.getId()+"");
|
|
|
+ if (!validate102Dto.getMessageFirst().equals(rmArray[0])){
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"调度应该传"+validate102Dto.getMessageFirst()+"帧并且原因是"+validate102Dto.getMessageReason()+",实际传"+IEC102Uitl.delimiterStringBySpace(receiveMessage)+",断开通道重启");
|
|
|
+ channelCloseConnect(ctx,uploadObject,uploadFileChannel);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("10".equals(rmArray[0])) {
|
|
|
+ // 获取控制域,根据功能码判断业务流
|
|
|
+ String fc = rmArray[1].substring(1);
|
|
|
+ if (FileConstant.validateMessage.get(uploadFileChannel.getId()+"")!=null){
|
|
|
+ // 需要校验接收的帧是否正确
|
|
|
+ Validate102Dto validate102Dto = FileConstant.validateMessage.get(uploadFileChannel.getId()+"");
|
|
|
+ if (!fc.equals(validate102Dto.getMessageReason())){
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"调度应该传10原因是"+validate102Dto.getMessageReason()+",实际传"+IEC102Uitl.delimiterStringBySpace(receiveMessage)+",断开通道重启");
|
|
|
+ channelCloseConnect(ctx,uploadObject,uploadFileChannel);
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("0".equals(fc)) {
|
|
|
+ receiveCtrlChinese = "复位通信";
|
|
|
+ // 回复链路
|
|
|
+ sendMessage = makeMessage10("00");
|
|
|
+ sendCtrlChinese = "确认复位";
|
|
|
+ } else if ("9".equals(fc)) {
|
|
|
+ receiveCtrlChinese = "召唤链路";
|
|
|
+ // 回复链路
|
|
|
+ sendMessage = makeMessage10("0B");
|
|
|
+ sendCtrlChinese = "回应链路请求帧";
|
|
|
+ } else if ("A".equals(fc)) {
|
|
|
+ receiveCtrlChinese = "召唤一级数据";
|
|
|
+ // 先判断文件上报次数累计的缓存变量是否存在
|
|
|
+ Map<String, FileMutableInteger> filterMap = FileConstant.uploadCountMap.entrySet().stream().filter(r -> uploadObject.getObjectNo().equals(r.getKey().substring(0, r.getKey().indexOf("@"))))
|
|
|
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
|
|
+ (oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
|
|
+ // 上报文件名
|
|
|
+ String fileNameKey = "";
|
|
|
+ String typeSign = "";
|
|
|
+ if (MapUtil.isNotEmpty(filterMap)) {
|
|
|
+ sendCtrlChinese = "子站向主站传输文件内容";
|
|
|
+ // 不是第一次要文件了
|
|
|
+ for (Map.Entry<String, FileMutableInteger> entry : filterMap.entrySet()) {
|
|
|
+ fileNameKey = entry.getKey();
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"上传文件===>"+entry.getKey());
|
|
|
+ typeSign = "199";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ sendCtrlChinese = "子站向主站传输基本文件信息";
|
|
|
+ // 从待上报的缓存中取一个文件放入次数变量中
|
|
|
+ Map<String, UploadFileLog> readyUploadFileMap = super.filterFileByObjectNo(uploadObject.getObjectNo(), FileConstant.readyUploadFileMap, log);
|
|
|
+ for (Map.Entry<String, UploadFileLog> entry : readyUploadFileMap.entrySet()) {
|
|
|
+ // 从待上报缓存中取一个加入到统计变量中
|
|
|
+ FileMutableInteger fileMutableInteger = new FileMutableInteger(0);
|
|
|
+ FileConstant.uploadCountMap.put(entry.getKey(), fileMutableInteger);
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"找到文件===>"+entry.getKey());
|
|
|
+ fileNameKey = entry.getKey();
|
|
|
+ typeSign = "198";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("68");
|
|
|
+ dto.setMessageReason("07,0D");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ }
|
|
|
+ if ("".equals(fileNameKey)) {
|
|
|
+ sendCtrlChinese = "不正常的回复";
|
|
|
+ sendMessage = "1000FFFFFE16";
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"主站不正常的调用,导致取不到文件无法上报");
|
|
|
+ } else {
|
|
|
+ // 生成传输文件的68帧
|
|
|
+ sendMessage = uploadFile68(typeSign, fileNameKey, electricField, uploadObject, uploadFileChannel, log);
|
|
|
+ }
|
|
|
+ } else if ("B".equals(fc)) {
|
|
|
+ receiveCtrlChinese = "召唤二级数据";
|
|
|
+ // 获取此通道下的上报文件
|
|
|
+ Map<String, UploadFileLog> readyUploadFileMap = super.filterFileByObjectNo(uploadObject.getObjectNo(), FileConstant.readyUploadFileMap, log);
|
|
|
+
|
|
|
+ if (MapUtil.isNotEmpty(readyUploadFileMap)) {
|
|
|
+ // 文件缓存中有上报文件
|
|
|
+ sendMessage = makeMessage10("29");
|
|
|
+ sendCtrlChinese = "希望向主站传输一级数据";
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("10");
|
|
|
+ dto.setMessageReason("A");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ } else {
|
|
|
+ // 没有文件
|
|
|
+ sendMessage = makeMessage10("09");
|
|
|
+ sendCtrlChinese = "没有文件需要上报";
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("10");
|
|
|
+ dto.setMessageReason("B");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 68开头报文判断传输原因
|
|
|
+ String cot = rmArray[9];
|
|
|
+ if ("07".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "主站允许本次文件请求";
|
|
|
+ sendMessage = "1020FFFF1E16";
|
|
|
+ sendCtrlChinese = "确认有一级数据";
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("10");
|
|
|
+ dto.setMessageReason("A");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ } else {
|
|
|
+ if ("0A".equals(cot)) {
|
|
|
+ // 上报成功
|
|
|
+ receiveCtrlChinese = "文件成功接收结束";
|
|
|
+ super.totalFileUploadNums(uploadObject, uploadFileChannel, "", log);
|
|
|
+ } else {
|
|
|
+ // 上报失败
|
|
|
+ receiveCtrlChinese = "error";
|
|
|
+ if ("0D".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "文件重复传输";
|
|
|
+ } else if ("0B".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "文件名错误";
|
|
|
+ } else if ("0C".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "文件过大(大于1MB)";
|
|
|
+ } else if ("0E".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "文件类型错误";
|
|
|
+ } else if ("10".equals(cot)) {
|
|
|
+ receiveCtrlChinese = "文件接收错误(长度、MD5校验等),发送方准备重新传输该文件";
|
|
|
+ }
|
|
|
+ super.totalFileUploadNums(uploadObject, uploadFileChannel, receiveCtrlChinese, log);
|
|
|
+ }
|
|
|
+ sendCtrlChinese = "对上一条命令确认";
|
|
|
+ sendMessage = "1000FFFFFE16";
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("10");
|
|
|
+ dto.setMessageReason("B");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"接收报文:[" + receiveCtrlChinese + "]" + IEC102Uitl.delimiterStringBySpace(receiveMessage));
|
|
|
+ log.info(ctx.channel().remoteAddress()+" - "+"发送报文:[" + sendCtrlChinese + "]" + IEC102Uitl.delimiterStringBySpace(sendMessage));
|
|
|
+ return sendMessage;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成10帧报文
|
|
|
+ * 格式说明:10|控制域|地址低字节|地址高字节|校验和|16
|
|
|
+ *
|
|
|
+ * @param ctrl 控制域字节
|
|
|
+ * @return 10帧报文
|
|
|
+ */
|
|
|
+ private String makeMessage10(String ctrl) {
|
|
|
+ String[] returnMessage = {"10", "ctrl", "FF", "FF", "crc", "16"};
|
|
|
+ String crc = IEC102Uitl.makeChecksum(ctrl + returnMessage[2] + returnMessage[3]);
|
|
|
+ returnMessage[1] = ctrl;
|
|
|
+ returnMessage[4] = crc;
|
|
|
+ String sendMessage = ArrayUtil.join(returnMessage, "");
|
|
|
+ return sendMessage.toUpperCase();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 传输文件的68帧报文
|
|
|
+ * crc校验和:从[控制域]到[校验和]之前
|
|
|
+ * 帧长:从[控制域]到[校验和]之前所有字节数
|
|
|
+ *
|
|
|
+ * @return 68帧报文
|
|
|
+ */
|
|
|
+ private String uploadFile68(String typeSign, String fileNameKey, ElectricField electricField, UploadObject uploadObject, UploadFileChannel uploadFileChannel, Logger log) {
|
|
|
+ String[] tempKey = new String[3];
|
|
|
+ tempKey[0] = fileNameKey.substring(0,fileNameKey.indexOf("@",0));
|
|
|
+ tempKey[1] = fileNameKey.substring(fileNameKey.indexOf("@",1)+1,fileNameKey.indexOf("@",2));
|
|
|
+ tempKey[2] = fileNameKey.substring(fileNameKey.indexOf("@",2)+1);
|
|
|
+ String charsetName = uploadObject.getUploadFileCharSetEnum().getMessage();
|
|
|
+ String sendMessage = "";
|
|
|
+ // 获取本地物理文件路径
|
|
|
+ String filePath = FileUtil.getFileUploadPath() + File.separator + "process" + File.separator + tempKey[0] + File.separator + tempKey[1] + File.separator + tempKey[2];
|
|
|
+
|
|
|
+ if ("198".equals(typeSign)) {
|
|
|
+ // 子站向主站传输文件基本信息(68|帧长低字节|帧长高字节|68|控制域|地址低字节|地址高字节|类型标识|可变限定词|传输原因|设备地址低字节|设备地址高字节|记录地址|文件名字节|文件类型|文件长度|文件内容MD5数字签名|校验和|16)
|
|
|
+ String[] returnMessage = {"68", "mlLow", "mlHeight", "68", "28", "FF", "FF", "C6", "01", "06", "FF", "FF", "00", "fileNameByte", "fileType", "fileContentAllLength", "fileContentMD5", "crc", "16"};
|
|
|
+ // 生成文件名
|
|
|
+ String fileName = tempKey[2];
|
|
|
+ byte[] tempFileNameBytes = null;
|
|
|
+ try {
|
|
|
+ tempFileNameBytes = fileName.getBytes(charsetName);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("转换文件名编码失败", e);
|
|
|
+ }
|
|
|
+ // 获取文件名称长度
|
|
|
+ String fileNameLength = uploadFileChannel.getUploadFileNameLengthEnum().getMessage();
|
|
|
+ String fileNameByte = ByteUtil.Byte2String(tempFileNameBytes);
|
|
|
+ returnMessage[13] = StrUtil.padAfter(fileNameByte.replace(" ", ""), Integer.parseInt(fileNameLength) * 2, '0');
|
|
|
+ // 生成类型标识
|
|
|
+ Map<String, Integer> codeMap = super.getFileCode();
|
|
|
+ returnMessage[14] = Integer.toHexString(codeMap.get(tempKey[1]));
|
|
|
+ String fileContentByte = "";
|
|
|
+ String tempContent = "";
|
|
|
+ try {
|
|
|
+ fileContentByte = nmCreateFileMessageHex(filePath, log, uploadObject.getId(), fileNameKey);
|
|
|
+ tempContent = new String(fileContentByte);
|
|
|
+ fileContentByte = ByteUtil.Byte2String(fileContentByte.getBytes(charsetName));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("没找到文件", e);
|
|
|
+ totalFileUploadNums(uploadObject, uploadFileChannel, e.toString(), log);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("读取本地文件失败", e);
|
|
|
+ totalFileUploadNums(uploadObject, uploadFileChannel, e.toString(), log);
|
|
|
+ }
|
|
|
+ fileContentByte = fileContentByte.replaceAll(" ", "");
|
|
|
+ returnMessage[15] = ByteUtil.bytesToHexStringFromHighToLow(ByteUtil.intToBytesFromLowToHigh(fileContentByte.length() / 2));
|
|
|
+ try {
|
|
|
+ returnMessage[16] = FileUtil.getMD5(tempContent.getBytes(charsetName));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("文件内容加密MD5失败", e);
|
|
|
+ }
|
|
|
+ // 计算校验和,获取从[控制域]到[校验和]之前的报文
|
|
|
+ StringBuffer tempSB = new StringBuffer("");
|
|
|
+ for (int i = 4; i <= 16; i++) {
|
|
|
+ tempSB.append(returnMessage[i]);
|
|
|
+ }
|
|
|
+ returnMessage[17] = IEC102Uitl.makeChecksum(tempSB.toString());
|
|
|
+ // 计算报文的帧长
|
|
|
+ String ml = StrUtil.padAfter(ByteUtil.decToHex(tempSB.length() / 2), 4, '0');
|
|
|
+ String mlLow = ml.substring(0, 2);
|
|
|
+ String mlHeight = ml.substring(2);
|
|
|
+ returnMessage[1] = mlLow;
|
|
|
+ returnMessage[2] = mlHeight;
|
|
|
+ sendMessage = ArrayUtil.join(returnMessage, "");
|
|
|
+ } else {
|
|
|
+ // 子站向主站传输文件内容(68|帧长低字节|帧长高字节|68|控制域|地址低字节|地址高字节|类型标识|可变限定词|传输原因|设备地址低字节|设备地址高字节|记录地址|文件内容在文件的起始地址|本帧文件数据长度|文件数据|校验和|16)
|
|
|
+ String[] returnMessage = {"68", "mlLow", "mlHeight", "68", "ctrl", "FF", "FF", "C7", "01", "reason", "FF", "FF", "00", "fileContentStartIndex", "fileContentLength", "fileContentByte", "crc", "16"};
|
|
|
+ String fileContentStartIndex = "";
|
|
|
+ // 获取缓存中文件内容
|
|
|
+ Map<String, String> fileContentMap = new HashMap<>();
|
|
|
+
|
|
|
+ String fileContentByte = "";
|
|
|
+ if (FileConstant.fileContentByIdxMap.get(fileNameKey) == null) {
|
|
|
+ // 缓存中没有文件内容则新生成文件内容报文
|
|
|
+ try {
|
|
|
+ fileContentByte = nmCreateFileMessageHex(filePath, log, uploadObject.getId(), fileNameKey);
|
|
|
+ fileContentByte = ByteUtil.Byte2String(fileContentByte.getBytes(charsetName));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("没找到文件", e);
|
|
|
+ totalFileUploadNums(uploadObject, uploadFileChannel, e.toString(), log);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("读取本地文件失败", e);
|
|
|
+ totalFileUploadNums(uploadObject, uploadFileChannel, e.toString(), log);
|
|
|
+ }
|
|
|
+ fileContentByte = fileContentByte.replaceAll(" ", "");
|
|
|
+ fileContentMap.put("contentByteIdx", "0");
|
|
|
+ } else {
|
|
|
+ fileContentMap = FileConstant.fileContentByIdxMap.get(fileNameKey);
|
|
|
+ fileContentByte = fileContentMap.get("fileContent");
|
|
|
+ }
|
|
|
+ // 获取通道单次文件传输字节
|
|
|
+ String singleByte = uploadFileChannel.getUploadFileSingleByteEnum().getMessage();
|
|
|
+ String ctrl = "";
|
|
|
+ String reason = "";
|
|
|
+ if (fileContentByte.length() <= Integer.parseInt(singleByte) * 2) {
|
|
|
+ // 一次可以传输完,生成控制域码
|
|
|
+ ctrl = "08";
|
|
|
+ reason = "08";
|
|
|
+
|
|
|
+ Integer idx = Integer.parseInt(fileContentMap.get("contentByteIdx"));
|
|
|
+ if (idx != 0) {
|
|
|
+ idx = idx + 1;
|
|
|
+ }
|
|
|
+ fileContentStartIndex = ByteUtil.bytesToHexStringFromHighToLow(ByteUtil.intToBytesFromLowToHigh(idx));
|
|
|
+ FileConstant.fileContentByIdxMap.remove(fileNameKey);
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("68");
|
|
|
+ dto.setMessageReason("0A");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ } else {
|
|
|
+ // 生成不是最后一帧控制域码
|
|
|
+ ctrl = "28";
|
|
|
+ reason = "09";
|
|
|
+ // 将剩余的文件内容报文存入缓存中
|
|
|
+ Map<String, String> tempContentMap = new HashMap<>();
|
|
|
+ tempContentMap.put("fileContent", fileContentByte.substring(Integer.parseInt(singleByte) * 2));
|
|
|
+ // 上次字节结束的位置
|
|
|
+ Integer lastIdx = Integer.parseInt(fileContentMap.get("contentByteIdx"));
|
|
|
+ if (lastIdx == 0) {
|
|
|
+ tempContentMap.put("contentByteIdx", String.valueOf(Integer.parseInt(singleByte) - 1));
|
|
|
+ fileContentStartIndex = ByteUtil.bytesToHexStringFromHighToLow(ByteUtil.intToBytesFromLowToHigh(0));
|
|
|
+ } else {
|
|
|
+ tempContentMap.put("contentByteIdx", String.valueOf(lastIdx + Integer.parseInt(singleByte)));
|
|
|
+ fileContentStartIndex = ByteUtil.bytesToHexStringFromHighToLow(ByteUtil.intToBytesFromLowToHigh(lastIdx + 1));
|
|
|
+ }
|
|
|
+ FileConstant.fileContentByIdxMap.put(fileNameKey, tempContentMap);
|
|
|
+ fileContentByte = fileContentByte.substring(0, Integer.parseInt(singleByte) * 2);
|
|
|
+
|
|
|
+ Validate102Dto dto = new Validate102Dto();
|
|
|
+ dto.setMessageFirst("10");
|
|
|
+ dto.setMessageReason("A");
|
|
|
+ FileConstant.validateMessage.put(uploadFileChannel.getId()+"",dto);
|
|
|
+ }
|
|
|
+
|
|
|
+ returnMessage[4] = ctrl;
|
|
|
+ returnMessage[9] = reason;
|
|
|
+ returnMessage[13] = fileContentStartIndex;
|
|
|
+ returnMessage[14] = ByteUtil.decToHex(fileContentByte.length() / 2);
|
|
|
+ returnMessage[15] = fileContentByte;
|
|
|
+
|
|
|
+ // 计算校验和,获取从[控制域]到[校验和]之前的报文
|
|
|
+ StringBuffer tempSB = new StringBuffer("");
|
|
|
+ for (int i = 4; i <= 15; i++) {
|
|
|
+ tempSB.append(returnMessage[i]);
|
|
|
+ }
|
|
|
+ returnMessage[16] = IEC102Uitl.makeChecksum(tempSB.toString());
|
|
|
+ // 计算报文的帧长
|
|
|
+ String ml = StrUtil.padAfter(ByteUtil.decToHex(tempSB.length() / 2), 4, '0');
|
|
|
+ String mlLow = ml.substring(0, 2);
|
|
|
+ String mlHeight = ml.substring(2);
|
|
|
+ returnMessage[1] = mlLow;
|
|
|
+ returnMessage[2] = mlHeight;
|
|
|
+ sendMessage = ArrayUtil.join(returnMessage, "");
|
|
|
+ }
|
|
|
+ return sendMessage.toUpperCase();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取文件内容转16进制报文
|
|
|
+ *
|
|
|
+ * @param filePath
|
|
|
+ * @param log
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String nmCreateFileMessageHex(String filePath, Logger log, Integer uploadObjectId, String fileNameKey) throws Exception {
|
|
|
+ InputStreamReader isr = null;
|
|
|
+ String fileMessageHex = "";
|
|
|
+ try {
|
|
|
+ isr = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
|
|
|
+ StringBuffer sb = new StringBuffer("");
|
|
|
+ int len1 = 0;
|
|
|
+ while ((len1 = isr.read()) != -1) {
|
|
|
+ sb.append((char) len1);
|
|
|
+ }
|
|
|
+ isr.close();
|
|
|
+ fileMessageHex = sb.toString();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("没找到文件", e);
|
|
|
+ throw e;
|
|
|
+ } finally {
|
|
|
+ if (isr != null) {
|
|
|
+ try {
|
|
|
+ isr.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fileMessageHex;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void channelCloseConnect(ChannelHandlerContext ctx, UploadObject uploadObject, UploadFileChannel uploadFileChannel){
|
|
|
+ // 传输帧类型不对,断开通道重启
|
|
|
+ Iterator<Map.Entry<String, FileMutableInteger>> countMap = FileConstant.uploadCountMap.entrySet().iterator();
|
|
|
+ while (countMap.hasNext()){
|
|
|
+ Map.Entry<String, FileMutableInteger> entry = countMap.next();
|
|
|
+ String key = entry.getKey();
|
|
|
+ if (key.contains(uploadObject.getObjectNo() + "@")){
|
|
|
+ countMap.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Iterator<Map.Entry<String, String>> contentMap = FileConstant.fileContentMap.entrySet().iterator();
|
|
|
+ while (contentMap.hasNext()){
|
|
|
+ Map.Entry<String,String> entry = contentMap.next();
|
|
|
+ String key = entry.getKey();
|
|
|
+ if (key.contains(uploadObject.getObjectNo() + "@")){
|
|
|
+ contentMap.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ FileConstant.validateMessage.remove(uploadFileChannel.getId()+"");
|
|
|
+ ctx.close();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|