package com.ycl.utils; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.ycl.platform.domain.entity.DeviceInfo; import com.ycl.platform.domain.entity.TMonitor; import com.ycl.platform.domain.result.SYS.TMonitorResult; import com.ycl.platform.domain.vo.CheckResult; import com.ycl.platform.domain.vo.CheckUtil; import com.ycl.platform.mapper.DeviceInfoMapper; import com.ycl.platform.mapper.TMonitorMapper; import com.ycl.platform.service.WorkOrderService; import com.ycl.utils.http.SelfHttpUtil; import com.ycl.utils.uuid.IdUtils; import constant.RedisConstant; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.*; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.SimpleDateFormat; import java.util.*; /** * @author xp * @date 2022/11/16 */ @Component @RequiredArgsConstructor @Slf4j public class CheckPointUtil { private final RedisTemplate redisTemplate; private final SelfHttpUtil selfHttpUtil; private final DeviceInfoMapper deviceInfoMapper; private final WorkOrderService workOrderService; private final TMonitorMapper monitorMapper; /** * 监测点位在线工具类 * * @return */ public TMonitorResult check(TMonitorResult monitor,Integer times) { // 先检测能否访问该ip的网页 ResponseEntity res = null; String prefix = "http://"; if ("127.0.0.1".equals(monitor.getIp())) { monitor.setPingOnline(Boolean.FALSE); log.error("ip有误"+monitor.getIp()); return monitor; } try { res = selfHttpUtil.get(prefix + monitor.getIp(), null, null); monitor.setPingOnline(Objects.nonNull(res) && HttpStatus.OK == res.getStatusCode()); } catch (Exception e) { monitor.setPingOnline(Boolean.FALSE); } // 如果http得到的不在线,那么再ping一下 boolean reachable = false; Integer checkTimes = 1; Integer offLineTimes = 0; Integer continueOffTimes = 0; List offTimeList = new ArrayList<>(); // 从Redis获取数据时进行类型安全的转换 Map map = null; Object mapObj = redisTemplate.opsForHash().get(RedisConstant.ONLINE_KEY, monitor.getNo()); if (mapObj != null) { map = (Map) mapObj; checkTimes = (Integer) map.get("checkTimes") + 1; offLineTimes = (Integer) map.get("offLineTimes"); continueOffTimes = (Integer) map.get("continueOffTimes"); Object offTimeListObj = map.get("offTimeList"); if (offTimeListObj instanceof List) { offTimeList = new ArrayList<>((List) offTimeListObj); } } else { map = new HashMap<>(); } if (!monitor.getPingOnline()) { reachable = checkPing(monitor, reachable); monitor.setPingOnline(reachable); } if (!monitor.getPingOnline()) { offLineTimes++; continueOffTimes++; //记录离线时间 Date now = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); offTimeList.add(dateFormat.format(now)); monitor.setOffLineTimeStr(offTimeList); //到达产生工单的阈值次数 if (continueOffTimes>=times) { //产生了工单才会存储离线时间,存储最近一次产生工单的这几个离线时间点 monitor.setCreateWorkOrder(Boolean.TRUE); //产生了一次工单则清除 continueOffTimes = 0; } }else { //如果在线了,清空连续离线次数,清空离线时间 continueOffTimes = 0; } map.put("checkTimes", checkTimes); map.put("offLineTimes", offLineTimes); map.put("continueOffTimes", continueOffTimes); map.put("offTimeList", offTimeList); redisTemplate.opsForHash().put(RedisConstant.ONLINE_KEY, monitor.getNo(), map); monitor.setCheckCount(checkTimes); monitor.setOffLineCount(offLineTimes); return monitor; } private boolean checkPing(TMonitorResult monitor, boolean reachable) { try { int[] sleepTimes = {5000, 15000, 30000}; for (int sleepTime : sleepTimes) { reachable = InetAddress.getByName(monitor.getIp()).isReachable(5000); if (reachable) { break; } Thread.sleep(sleepTime); } } catch (Exception e) { log.error("Ping异常",e); } return reachable; } /** * 监测点位在线 * * @return */ public CheckResult webCheck(CheckUtil checkUtil) { CheckResult result = new CheckResult(); List ips = new LambdaQueryChainWrapper<>(monitorMapper) .eq(TMonitor::getSerialNumber, checkUtil.getSerialNumber()) .list(); if (ips.size() < 1) { result.setStatus("国标码未查找到IP"); return result; } checkUtil.setIp(ips.get(0).getIp()); log.info("监测IP:" + checkUtil.getIp()); String prefix = "http://"; if ("127.0.0.1".equals(checkUtil.getIp())) { result.setStatus("ip异常"); return result; } boolean webReachable = false; try { ResponseEntity res = selfHttpUtil.get(prefix + checkUtil.getIp(), null, null); webReachable = Objects.nonNull(res) && HttpStatus.OK == res.getStatusCode(); } catch (Exception e) { log.info("检测web异常" + e.getMessage()); webReachable = Boolean.FALSE; } // ping boolean pingReachable = false; try { InetAddress inet = InetAddress.getByName(checkUtil.getIp()); pingReachable = inet.isReachable(5000); // 5000毫秒超时时间 } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String imgUrl = ""; if (pingReachable || webReachable) { // 查出国标设备,就一条数据 List gbDevices = new LambdaQueryChainWrapper<>(deviceInfoMapper) .orderByDesc(DeviceInfo::getUpdateTime) .last("limit 1") .list(); if (!CollectionUtils.isEmpty(gbDevices)) { try { imgUrl = workOrderService.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), checkUtil.getSerialNumber(), IdUtils.workOrderNO(new Date(), "99999")); result.setImg(imgUrl); } catch (Exception e) { e.printStackTrace(); } } } String status = ""; if (!webReachable) { status += "设备web访问失败;"; } else if (webReachable) { status += "设备web访问正常;"; } if (!pingReachable) { status += "设备ip未ping通;"; } else if (pingReachable) { status += "设备ipPing正常;"; } if (StringUtils.isEmpty(imgUrl)) { status += "未获取到图片"; } else { status += "获取图片正常"; } result.setStatus(status); return result; } /** * ping * * @return */ public CheckResult ping(CheckUtil checkUtil) { CheckResult result = new CheckResult(); log.info("监测IP:" + checkUtil.getIp()); String prefix = "http://"; if ("127.0.0.1".equals(checkUtil.getIp())) { result.setStatus("ip异常"); return result; } // ping boolean pingReachable = false; try { InetAddress inet = InetAddress.getByName(checkUtil.getIp()); pingReachable = inet.isReachable(5000); // 5000毫秒超时时间 } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String status = ""; if (!pingReachable) { status += "ip未ping通;"; } else { status += "成功"; } result.setStatus(status); return result; } }