|
@@ -1,30 +1,21 @@
|
|
|
package com.persagy.client;
|
|
|
|
|
|
-import cn.hutool.core.collection.CollectionUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.date.TimeInterval;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
-import com.alibaba.fastjson.TypeReference;
|
|
|
-import com.persagy.cache.AlarmLastTimeCache;
|
|
|
import com.persagy.cache.CreatedAlarmIdsCache;
|
|
|
-import com.persagy.entity.AlarmDefine;
|
|
|
import com.persagy.entity.NettyMessage;
|
|
|
-import com.persagy.entity.v2.AlarmCondition;
|
|
|
-import com.persagy.entity.v2.ObjConditionRel;
|
|
|
+import com.persagy.enumeration.NettyMsgTypeEnum;
|
|
|
import com.persagy.job.NettyMessageQueue;
|
|
|
-import com.persagy.repository.AlarmRecordRepository;
|
|
|
-import com.persagy.service.impl.AlarmConditionServiceImpl;
|
|
|
-import com.persagy.utils.LockUtil;
|
|
|
+import com.persagy.service.impl.NettyMsgHandler;
|
|
|
import com.persagy.utils.StringUtil;
|
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
|
import io.netty.handler.timeout.IdleState;
|
|
|
import io.netty.handler.timeout.IdleStateEvent;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
-import java.util.List;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
/**
|
|
@@ -41,24 +32,19 @@ public class GroupNettyClientHandler extends ChannelInboundHandlerAdapter {
|
|
|
// Reconnect when the server sends nothing for 10 seconds.
|
|
|
private static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("readTimeout", "10"));
|
|
|
|
|
|
- private AlarmConditionServiceImpl alarmConditionService;
|
|
|
private GroupNettyClient groupNettyClient;
|
|
|
- private AlarmRecordRepository alarmRecordRepository;
|
|
|
private CreatedAlarmIdsCache createdAlarmIdsCache;
|
|
|
- private AlarmLastTimeCache alarmLastTimeCache;
|
|
|
+ private NettyMsgHandler nettyMsgHandler;
|
|
|
|
|
|
|
|
|
public GroupNettyClientHandler(
|
|
|
GroupNettyClient groupNettyClient,
|
|
|
- AlarmConditionServiceImpl alarmConditionService,
|
|
|
- AlarmRecordRepository alarmRecordRepository,
|
|
|
- CreatedAlarmIdsCache createdAlarmIdsCache,
|
|
|
- AlarmLastTimeCache alarmLastTimeCache) {
|
|
|
- this.alarmConditionService = alarmConditionService;
|
|
|
+ NettyMsgHandler nettyMsgHandler,
|
|
|
+ CreatedAlarmIdsCache createdAlarmIdsCache
|
|
|
+ ) {
|
|
|
this.groupNettyClient = groupNettyClient;
|
|
|
- this.alarmRecordRepository = alarmRecordRepository;
|
|
|
this.createdAlarmIdsCache = createdAlarmIdsCache;
|
|
|
- this.alarmLastTimeCache = alarmLastTimeCache;
|
|
|
+ this.nettyMsgHandler = nettyMsgHandler;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -84,10 +70,12 @@ public class GroupNettyClientHandler extends ChannelInboundHandlerAdapter {
|
|
|
@Override
|
|
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
|
|
log.info("Connected to: " + ctx.channel().remoteAddress());
|
|
|
- ctx.channel().writeAndFlush(new NettyMessage<>(200, groupNettyClient.projectId).toString());
|
|
|
+ ctx.channel().writeAndFlush(new NettyMessage<>(
|
|
|
+ NettyMsgTypeEnum.CONNECT, groupNettyClient.projectId).toString());
|
|
|
//启动的时候发送消息,获取全部报警定义
|
|
|
//{"groupCode":"wd", "projectId":"Pj123"}
|
|
|
- NettyMessage nettyMessage = new NettyMessage(4, groupNettyClient.projectId);
|
|
|
+ NettyMessage nettyMessage = new NettyMessage(
|
|
|
+ NettyMsgTypeEnum.REQUEST_ALL_CONFIGS, groupNettyClient.projectId);
|
|
|
nettyMessage.setRemark("连接已经建立;");
|
|
|
JSONObject content = new JSONObject();
|
|
|
content.put("groupCode", groupNettyClient.groupCode);
|
|
@@ -123,17 +111,19 @@ public class GroupNettyClientHandler extends ChannelInboundHandlerAdapter {
|
|
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
|
|
if (StringUtil.isJSONObject((String) msg)) {
|
|
|
NettyMessage message = StringUtil.tranferItemToDTO((String) msg, NettyMessage.class);
|
|
|
- if (message.getOpCode() != 9) {
|
|
|
- log.info("Client received: {}", msg);
|
|
|
+ if (message.getOpCode() == NettyMsgTypeEnum.ALL_CONDITIONS) {
|
|
|
+ log.info("获取到全量的报警条件, 共[{}]条", message.getContent().size());
|
|
|
+ } else if (message.getOpCode() == NettyMsgTypeEnum.ALL_OBJ_CONDITION_REL) {
|
|
|
+ log.info("正在同步设备与报警条件的关联关系, 共[{}]条", message.getContent().size());
|
|
|
} else {
|
|
|
- log.info("全量获取报警定义完成");
|
|
|
+ log.info("接收到netty消息: {}", msg);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
TimeInterval timer = DateUtil.timer();
|
|
|
handlerMsg(ctx, msg);
|
|
|
- log.info("处理消息时间[{}]", timer.interval());
|
|
|
+ log.debug("处理消息时间[{}]", timer.interval());
|
|
|
} catch (Exception e) {
|
|
|
log.error("channelRead", e);
|
|
|
}
|
|
@@ -142,88 +132,54 @@ public class GroupNettyClientHandler extends ChannelInboundHandlerAdapter {
|
|
|
public void handlerMsg(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
|
|
|
if (StringUtil.isJSONObject((String) msg)) {
|
|
|
NettyMessage message = StringUtil.tranferItemToDTO((String) msg, NettyMessage.class);
|
|
|
- if (message.getOpCode() == 9) {
|
|
|
- log.info("开始全量同步报警条件");
|
|
|
- cacheAlarmConditions(msg);
|
|
|
- } else if (message.getOpCode() == 7) {
|
|
|
- NettyMessage<AlarmDefine> alarmDefineNettyMessage = JSONObject.parseObject(
|
|
|
- String.valueOf(msg),
|
|
|
- new TypeReference<NettyMessage<AlarmDefine>>() {
|
|
|
- });
|
|
|
- List<AlarmDefine> definesList = alarmDefineNettyMessage.getContent();
|
|
|
- if (CollectionUtil.isNotEmpty(definesList)) {
|
|
|
- alarmConditionService.listSomeAlarmDefine(definesList);
|
|
|
- }
|
|
|
- } else if (message.getOpCode() == 10) {
|
|
|
- NettyMessage<AlarmDefine> alarmDefineNettyMessage = JSONObject.parseObject(String.valueOf(msg), new TypeReference<NettyMessage<AlarmDefine>>() {
|
|
|
- });
|
|
|
- List<AlarmDefine> definesList = alarmDefineNettyMessage.getContent();
|
|
|
- if (CollectionUtil.isNotEmpty(definesList)) {
|
|
|
- alarmConditionService.deleteAlarmDefine(definesList);
|
|
|
- }
|
|
|
- } else if (message.getOpCode() == 8) {
|
|
|
- log.info("云端完成报警记录创建");
|
|
|
- log.info("返回报警记录id[{}]", message);
|
|
|
- //{"id":"","objId":"","itemCode":""} id为报警记录ID
|
|
|
-
|
|
|
- List content = message.getContent();
|
|
|
- if (CollectionUtil.isNotEmpty(content)) {
|
|
|
- JSONObject parseObject = JSONObject.parseObject(JSONObject.toJSONString(content.get(0)));
|
|
|
- String alarmId = parseObject.getString("id");
|
|
|
- // 将alarmId放入缓存中,用于后续判断报警是否完成创建
|
|
|
- createdAlarmIdsCache.put(alarmId);
|
|
|
- alarmLastTimeCache.setAlarmHasCreated(alarmId);
|
|
|
- }
|
|
|
- } else if (message.getOpCode() == 11) {
|
|
|
- log.info("正在同步报警条件与设备的关联关系");
|
|
|
- NettyMessage<ObjConditionRel> objConditionRelNettyMessage = JSONObject.parseObject(
|
|
|
- String.valueOf(msg),
|
|
|
- new TypeReference<NettyMessage<ObjConditionRel>>() {
|
|
|
- });
|
|
|
-
|
|
|
- List<ObjConditionRel> content = objConditionRelNettyMessage.getContent();
|
|
|
- if (CollectionUtils.isEmpty(content)) {
|
|
|
- log.info("接收到的消息中报警条件与设备的关联关系为空");
|
|
|
- }
|
|
|
- log.info("报警条件与设备的关联关系 -> 项目id:[{}], 同步条数[{}]",
|
|
|
- content.get(0).getProjectId(), content.size());
|
|
|
- alarmConditionService.cacheObjConditionRels(content);
|
|
|
- }
|
|
|
- NettyMessage response = new NettyMessage(groupNettyClient.projectId);
|
|
|
- response.setOpCode(3);
|
|
|
- response.setRemark("已经收到消息");
|
|
|
- channelHandlerContext.write(response.toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 缓存报警条件
|
|
|
- *
|
|
|
- * @param msg 全量报警条件消息
|
|
|
- * @author lixing
|
|
|
- * @version V1.0 2021/10/22 3:21 下午
|
|
|
- */
|
|
|
- private void cacheAlarmConditions(Object msg) {
|
|
|
- NettyMessage<AlarmCondition> alarmConditionNettyMessage = JSONObject.parseObject(
|
|
|
- String.valueOf(msg),
|
|
|
- new TypeReference<NettyMessage<AlarmCondition>>() {
|
|
|
- });
|
|
|
- List<AlarmCondition> conditionList = alarmConditionNettyMessage.getContent();
|
|
|
- if (CollectionUtil.isNotEmpty(conditionList)) {
|
|
|
- try {
|
|
|
- LockUtil.getInstance().lock.lock();
|
|
|
- LockUtil.getInstance().setExecute(false);
|
|
|
- //加个等待,保证正在执行的逻辑执行成功
|
|
|
- Thread.sleep(4000);
|
|
|
- alarmConditionService.cacheAllConditions(conditionList);
|
|
|
- LockUtil.getInstance().setExecute(true);
|
|
|
- LockUtil.getInstance().condition.signalAll();
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("全量同步报警条件发生异常", e);
|
|
|
- } finally {
|
|
|
- LockUtil.getInstance().lock.unlock();
|
|
|
+ NettyMsgTypeEnum opCode = message.getOpCode();
|
|
|
+ // 通过增加synchronized关键字控制同一类消息顺序执行,
|
|
|
+ // 避免出现同时更新导致的异常。例如:先接到删除数据的信息,又接到新增数据的信息
|
|
|
+ // 如果不保证执行顺序,很可能无法得到想要的结果
|
|
|
+ switch (opCode) {
|
|
|
+ case ALL_CONDITIONS:
|
|
|
+ synchronized ("sync_condition") {
|
|
|
+ nettyMsgHandler.cacheAllAlarmConditions(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case NEW_CONDITION:
|
|
|
+ synchronized ("sync_condition") {
|
|
|
+ nettyMsgHandler.cacheNewCondition(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case UPDATE_CONDITION:
|
|
|
+ synchronized ("sync_condition") {
|
|
|
+ nettyMsgHandler.cacheUpdatedCondition(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DELETE_CONDITION:
|
|
|
+ synchronized ("sync_condition") {
|
|
|
+ nettyMsgHandler.removeCachedCondition(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ALL_OBJ_CONDITION_REL:
|
|
|
+ synchronized ("sync_obj_condition_rel") {
|
|
|
+ nettyMsgHandler.cacheAllObjConditionRel(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case NEW_OBJ_CONDITION_REL:
|
|
|
+ synchronized ("sync_obj_condition_rel") {
|
|
|
+ nettyMsgHandler.cacheNewObjConditionRel(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DELETE_OBJ_CONDITION_REL:
|
|
|
+ synchronized ("sync_obj_condition_rel") {
|
|
|
+ nettyMsgHandler.removeCachedObjConditionRel(msg);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case RECORD_ID:
|
|
|
+ nettyMsgHandler.cacheRecordId(message);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
+ // 发送已接收回执
|
|
|
+ nettyMsgHandler.acceptedReply(channelHandlerContext);
|
|
|
}
|
|
|
}
|
|
|
|