package com.cisdi.data.caliper.gateway; import com.cisdi.data.common.dto.AlarmDto; import com.cisdi.data.sdk.consts.ServiceName; import com.cisdi.data.sdk.service.AlarmService; import lombok.extern.slf4j.Slf4j; import java.util.*; @Slf4j public class CaliperDaemonTask implements Runnable { private CaliperClient caliperClient; private final CaliperTaskStartVo startVo; public CaliperDaemonTask(CaliperClient caliperClient, CaliperTaskStartVo startVo) { this.caliperClient = caliperClient; this.startVo = startVo; } @Override public void run() { final String[] channelInfo = {null}; Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { channelInfo[0] = startChannel(); if (!startVo.getShouldRun().get()) { timer.cancel(); } } }, 0, startVo.getSocketParam().getPullInternal()); if (caliperClient != null) { caliperClient.close(); caliperClient = null; } log.info("退出Caliper拉取连接线程 {}", channelInfo[0]); } private String startChannel() { String channelInfo = String.format("channel:%s, active:%s,open:%s,writable:%s", caliperClient.getChannel(), caliperClient.getChannel() == null ? "" : caliperClient.getChannel().isActive(), caliperClient.getChannel() == null ? "" : caliperClient.getChannel().isOpen(), caliperClient.getChannel() == null ? "" : caliperClient.getChannel().isWritable()); try { if (caliperClient != null && caliperClient.getChannel() != null && caliperClient.getChannel().isActive()) { if (startVo.getGatewayBase() != null && Boolean.TRUE.equals(startVo.getGatewayBase().getInstanceVo().getLogOpen())) { log.info("当前Caliper拉取连接通道处于连接状态,连接id:{},连接信息:{}", startVo.getGatewayBase().getInstanceVo().getRunId(), channelInfo); } if (startVo.getCustomParam() != null && Boolean.TRUE.equals(startVo.getCustomParam().getEnableHeartbeat()) && Math.abs(System.currentTimeMillis() - caliperClient.getLastHeartbeatTime()) > (long) startVo.getCustomParam().getHeartbeatMaxLostCount() * startVo.getCustomParam().getHeartbeatTimeInMs()) { log.warn("当前Caliper拉取连接通道心跳启用,且心跳超时,触发重连,连接id:{},连接信息:{}", startVo.getGatewayBase().getInstanceVo().getRunId(), channelInfo); //启用了心跳,且心跳时间超时 reconnect(channelInfo, true); } } else { assert caliperClient != null; if (caliperClient.getChannel() == null) { String errorMsg = String.format("Caliper到%s:%s的连接未建立或已关闭, %s", caliperClient.getIp(), caliperClient.getPort(), channelInfo); log.warn(errorMsg); sendAlarmToPlatform(errorMsg); reconnect(channelInfo, false); } else { String errorMsg = String.format("Caliper到%s:%s的连接未建立或已关闭, %s", caliperClient.getIp(), caliperClient.getPort(), channelInfo); log.warn(errorMsg); sendAlarmToPlatform(errorMsg); if (startVo.getCustomParam() != null && Boolean.TRUE.equals(startVo.getCustomParam().getEnableHeartbeat()) && Math.abs(System.currentTimeMillis() - caliperClient.getLastHeartbeatTime()) > (long) startVo.getCustomParam().getHeartbeatMaxLostCount() * startVo.getCustomParam().getHeartbeatTimeInMs()) { log.warn("当前Caliper拉取连接通道心跳启用,且心跳超时,触发重连,连接id:{},连接信息:{}", startVo.getGatewayBase().getInstanceVo().getRunId(), channelInfo); //启用了心跳,且心跳时间超时 reconnect(channelInfo, true); } } } } catch (Exception e) { log.warn(e.getMessage(), e); } return channelInfo; } private void reconnect(final String copyChannelInfo, boolean forceConnect) throws InterruptedException { Thread.sleep(5000); Thread thread = new Thread(() -> { try { log.info("Caliper触发重连强制:{}....{}:{} {}", forceConnect, caliperClient.getIp(), caliperClient.getPort(), copyChannelInfo); if (caliperClient.getChannel() == null || forceConnect) { caliperClient.reconnect(); } } catch (Exception e) { log.info(e.getMessage(), e); } }); thread.start(); } private void sendAlarmToPlatform(String detail) { if (startVo.getServiceProvider() != null && startVo.getGatewayBase() != null) { AlarmService alarmService = (AlarmService) startVo.getServiceProvider().getByName(ServiceName.Alarm); if (alarmService != null) { AlarmDto alarmDto = new AlarmDto(); alarmDto.setAlarmType(AlarmDto.Connect_Fail_Alarm); alarmDto.setDetail(detail); alarmDto.setDeviceId(startVo.getDeviceId()); alarmDto.setGatewayId(startVo.getGatewayBase().getInstanceVo().getRunId()); alarmDto.setGatewayName(startVo.getGatewayBase().getInstanceVo().getName()); alarmDto.setMsgKey(null); alarmDto.setUpper(Boolean.TRUE); alarmDto.setTime(new Date()); alarmService.raiseAlarm(Collections.singletonList(alarmDto)); } } } }