|  |  |  | 
|---|
|  |  |  | import com.dy.rtuMw.server.forTcp.TcpSessionCache; | 
|---|
|  |  |  | import com.dy.rtuMw.server.local.CommandInnerDeaLer; | 
|---|
|  |  |  | import com.dy.rtuMw.server.local.ReturnCommand; | 
|---|
|  |  |  | import com.dy.rtuMw.server.mqtt.DevStatusDealer; | 
|---|
|  |  |  | import com.dy.rtuMw.server.mqtt.MqttManager; | 
|---|
|  |  |  | import com.dy.rtuMw.server.msCenter.MsCenterUnit; | 
|---|
|  |  |  | import com.dy.rtuMw.server.tasks.WebDownCom4MqttTask; | 
|---|
|  |  |  | import com.dy.rtuMw.server.tasks.WebDownComTask; | 
|---|
|  |  |  | import com.dy.common.mw.core.CoreUnit; | 
|---|
|  |  |  | import com.dy.common.mw.protocol.Command; | 
|---|
|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @GetMapping("/rtuLogFile") | 
|---|
|  |  |  | public void rtuLogFile(String rtuAddr, HttpServletRequest req, HttpServletResponse rep){ | 
|---|
|  |  |  | File logFile = ResourceUnit.getInstance().getLogFile(rtuAddr + ".log") ; | 
|---|
|  |  |  | logFile(rtuAddr, req, rep) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 下载控制器(RTU)上下行数据的log日志文件 | 
|---|
|  |  |  | * @param devId | 
|---|
|  |  |  | * @param req | 
|---|
|  |  |  | * @param rep | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @GetMapping("/mqttDevLogFile") | 
|---|
|  |  |  | public void mqttDevLogFile(String devId, HttpServletRequest req, HttpServletResponse rep){ | 
|---|
|  |  |  | logFile(devId, req, rep) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | private void logFile(String fileName, HttpServletRequest req, HttpServletResponse rep){ | 
|---|
|  |  |  | File logFile = ResourceUnit.getInstance().getLogFile(fileName + ".log") ; | 
|---|
|  |  |  | if(logFile != null && logFile.exists()){ | 
|---|
|  |  |  | //在Spring Boot中,application/octet-stream;charset=UTF-8通常表示响应的内容是字节流, | 
|---|
|  |  |  | //并且字符集是UTF-8。对于这种类型的响应,Spring Boot默认使用ByteArrayHttpMessageConverter来处理, | 
|---|
|  |  |  | 
|---|
|  |  |  | //字符集通常用于文本内容,而application/octet-stream通常用于二进制内容,因此在这种情况下指定字符集可能是不合适的。 | 
|---|
|  |  |  | //不过,如果你确实需要处理带有特定字符集的application/octet-stream响应,你可能需要自定义HttpMessageConverter。 | 
|---|
|  |  |  | rep.addHeader("content-type", "application/octet-stream;charset=UTF-8"); | 
|---|
|  |  |  | rep.addHeader("Content-Disposition", "attachment;fileName=" + (rtuAddr + ".log")) ; | 
|---|
|  |  |  | rep.addHeader("Content-Disposition", "attachment;fileName=" + (fileName + ".log")) ; | 
|---|
|  |  |  | ServletOutputStream out = null; | 
|---|
|  |  |  | FileInputStream in = null ; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @GetMapping("/rtuLogText") | 
|---|
|  |  |  | public BaseResponse<List<String>> rtuLogText(String rtuAddr){ | 
|---|
|  |  |  | return logText(rtuAddr, true) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 下载控制器(RTU)上下行数据的log日志文件 | 
|---|
|  |  |  | * @param devId | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @GetMapping("/mqttDevLogText") | 
|---|
|  |  |  | public BaseResponse<List<String>> mqttDevLogText(String devId){ | 
|---|
|  |  |  | return logText(devId, false) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 下载控制器(RTU)上下行数据的log日志文件 | 
|---|
|  |  |  | * @param fileName | 
|---|
|  |  |  | * @param reverseOrder | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private BaseResponse<List<String>> logText(String fileName, boolean reverseOrder){ | 
|---|
|  |  |  | List<String> list ; | 
|---|
|  |  |  | File logFile = ResourceUnit.getInstance().getLogFile(rtuAddr + ".log") ; | 
|---|
|  |  |  | File logFile = ResourceUnit.getInstance().getLogFile(fileName + ".log") ; | 
|---|
|  |  |  | if(logFile != null && logFile.exists()){ | 
|---|
|  |  |  | BufferedReader reader = null ; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | reader = new BufferedReader(new FileReader(logFile)) ; | 
|---|
|  |  |  | //新的实现方法 | 
|---|
|  |  |  | Stream<String> linesStream = reader.lines() ; | 
|---|
|  |  |  | //list = linesStream.toList() ; //按原来顺序 | 
|---|
|  |  |  | list = linesStream.sorted(Comparator.reverseOrder()).collect(Collectors.toList()) ;//倒序 | 
|---|
|  |  |  | /* 原来的实现方法 | 
|---|
|  |  |  | list = new ArrayList() ; | 
|---|
|  |  |  | String line ; | 
|---|
|  |  |  | while((line = reader.readLine()) != null){ | 
|---|
|  |  |  | list.add(line) ; | 
|---|
|  |  |  | if(reverseOrder){ | 
|---|
|  |  |  | list = linesStream.sorted(Comparator.reverseOrder()).collect(Collectors.toList()) ;//倒序 | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | list = linesStream.toList() ; //按原来顺序 | 
|---|
|  |  |  | } | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(list); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | list = new ArrayList() ; | 
|---|
|  |  |  | list.add("读取控制器(" + rtuAddr + ")的日志文件异常:" + (e.getMessage() == null?"":("," + e.getMessage()))) ; | 
|---|
|  |  |  | list.add("读取控制器(" + fileName + ")的日志文件异常:" + (e.getMessage() == null?"":("," + e.getMessage()))) ; | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(list); | 
|---|
|  |  |  | }finally{ | 
|---|
|  |  |  | if(reader != null){ | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | list = new ArrayList() ; | 
|---|
|  |  |  | list.add("未得到控制器(" + rtuAddr + ")的日志文件") ; | 
|---|
|  |  |  | list.add("未得到控制器(" + fileName + ")的日志文件") ; | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(list); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | }catch(Exception e){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("处理发向RTU的外部透传命令出错" + (e.getMessage() == null?"":("," + e.getMessage())), com.getId(), com.getCode()) ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else if(commandType.equals(CommandType.mqttCommand)){ | 
|---|
|  |  |  | //发向MQTT的外部命令 | 
|---|
|  |  |  | try{ | 
|---|
|  |  |  | return this.dealMqttCommand(com) ; | 
|---|
|  |  |  | }catch(Exception e){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("处理发向RTU的外部命令出错" + (e.getMessage() == null?"":("," + e.getMessage())), com.getId(), com.getCode()) ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else if(commandType.equals(CommandType.resultCommand)){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,通信中间件不接结果类型的命令!", com.getId(), com.getCode())); | 
|---|
|  |  |  | }else{ | 
|---|
|  |  |  | 
|---|
|  |  |  | CoreUnit.getInstance().pushCoreTask(task); | 
|---|
|  |  |  | }catch(Exception e){ | 
|---|
|  |  |  | log.error(e.getMessage(), e); | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.successed("透传命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ; | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("透传命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(ReturnCommand.successed("透传命令已接受,即将构造并下发命令。", command.getId(), command.getCode())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 处理发向MQTT的外部命令 | 
|---|
|  |  |  | * @return 结果 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private BaseResponse<Command> dealMqttCommand(Command command){ | 
|---|
|  |  |  | String mqttDevId = command.getRtuAddr() ;//FBox设备号 | 
|---|
|  |  |  | if(mqttDevId == null || mqttDevId.trim().equals("")){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备ID为空!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!ServerProperties.mqttUnitEnable.booleanValue()){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接模块配置未启动!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(MqttManager.getInstance().poolIsClose()){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接池未创建成功!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!DevStatusDealer.oneOnLine(mqttDevId)){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备未在线!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //生成异步任务 | 
|---|
|  |  |  | WebDownCom4MqttTask task = new WebDownCom4MqttTask() ; | 
|---|
|  |  |  | task.data = command ; | 
|---|
|  |  |  | try{ | 
|---|
|  |  |  | log.info("构造下发MQTT命令" + command.getCode() + "的核心任务,并放入任务队列中"); | 
|---|
|  |  |  | CoreUnit.getInstance().pushCoreTask(task); | 
|---|
|  |  |  | }catch(Exception e){ | 
|---|
|  |  |  | log.error(e.getMessage(), e); | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.successed("MQTT命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(ReturnCommand.successed("MQTT命令已接受,即将构造并下发命令。", command.getId(), command.getCode())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 处理发向MQTT的内部部命令 | 
|---|
|  |  |  | * @return 结果 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private BaseResponse<Command> dealMqttInnerCommand(Command command){ | 
|---|
|  |  |  | String mqttDevId = command.getRtuAddr() ;//FBox设备号 | 
|---|
|  |  |  | if(mqttDevId == null || mqttDevId.trim().equals("")){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备ID为空!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!ServerProperties.mqttUnitEnable.booleanValue()){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接模块配置未启动!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(MqttManager.getInstance().poolIsClose()){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接池未创建成功!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!DevStatusDealer.oneOnLine(mqttDevId)){ | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备未在线!", command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //生成异步任务 | 
|---|
|  |  |  | WebDownCom4MqttTask task = new WebDownCom4MqttTask() ; | 
|---|
|  |  |  | task.data = command ; | 
|---|
|  |  |  | try{ | 
|---|
|  |  |  | log.info("构造下发MQTT命令" + command.getCode() + "的核心任务,并放入任务队列中"); | 
|---|
|  |  |  | CoreUnit.getInstance().pushCoreTask(task); | 
|---|
|  |  |  | }catch(Exception e){ | 
|---|
|  |  |  | log.error(e.getMessage(), e); | 
|---|
|  |  |  | return BaseResponseUtils.buildError(ReturnCommand.successed("MQTT命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return BaseResponseUtils.buildSuccess(ReturnCommand.successed("MQTT命令已接受,即将构造并下发命令。", command.getId(), command.getCode())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|