dacoo-data-sdk-yongfeng/src/main/java/com/cisdi/data/AMETEKSurfaceVision/gateway/SurfaceVisionIoSession.java

292 lines
10 KiB
Java
Raw Normal View History

2024-09-04 14:38:10 +08:00
package com.cisdi.data.AMETEKSurfaceVision.gateway;
import com.alibaba.fastjson.JSON;
import com.cisdi.data.AMETEKSurfaceVision.DynamicCodeActionParamDTO;
import com.cisdi.data.AMETEKSurfaceVision.DynamicCodeActionParamDTO.PropertyConfig;
import com.cisdi.data.common.exception.BusinessException;
import com.cisdi.data.sdk.consts.ServiceName;
import com.cisdi.data.sdk.gateway.message.SocketMessage;
import com.cisdi.data.sdk.gateway.netty.IoSession;
import com.cisdi.data.sdk.gateway.netty.impl.AbstractIoSession;
import com.cisdi.data.sdk.service.DynamicCodecService;
import com.cisdi.data.sdk.service.SendService;
import com.cisdi.data.sdk.service.Service;
import com.cisdi.data.sdk.vo.ExeResultVo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 表检仪协议会话
*
* @author tzz
*/
public class SurfaceVisionIoSession extends AbstractIoSession implements IoSession {
private long lastAliveTime = System.currentTimeMillis();
private static Logger logger = LoggerFactory.getLogger(SurfaceVisionIoSession.class);
private String deviceId = null;
private String gwPrefixCache = null;
private final static byte[] beat = {0x07,0x7C,0x24,0x0D,0x0A};
private int count = 1;
// 初始化为0的原子整型变量作为计数器,用作发送命令的replayId,初始值为1
/** 当前下发命令replayId */
private Integer currentCount = -1;
public void setCurrentSend(SurfaceVisionSocketReturnMessage currentSend) {
this.currentSend = currentSend;
}
/** 当前下发命令信息 */
private SurfaceVisionSocketReturnMessage currentSend = null;
public void increment() {
if (count < SurfaceVisionConstants.MAX_COUNT) {
count++;
// 自增1并返回新值
}
else {
count = 1;
}
}
public int getCount() {
return count;
// 获取当前计数器的值
}
public SurfaceVisionIoSession(String deviceId) {
this.deviceId = deviceId;
}
@Override
public String[] getDeviceIds() {
return new String[0];
}
/** 获取当前下发电文点位配置信息 */
private List<PropertyConfig> getPropertyConfig(String msgKeyName){
//获取DynamicService
Service service = serviceProvider.getByName(ServiceName.DynamicCodec);
if (service == null || !(service instanceof DynamicCodecService)) {
throw new BusinessException("获取DynamicService失败");
}
//获取网关ID
String runId = socketGateway.getInstanceVo().getRunId();
//获取点位配置信息
DynamicCodecService dynamicCodecService = (DynamicCodecService)service;
String actionParam = dynamicCodecService.findByRunIdAndMsgKey(runId, msgKeyName);
DynamicCodeActionParamDTO dto = null;
try {
dto = JSON.parseObject(actionParam, DynamicCodeActionParamDTO.class);
} catch (Exception e) {
throw new BusinessException("连接id:" + runId + "电文号:" + msgKeyName + "json转换错误", e);
}
if (dto == null || dto.getPropertyList() == null || dto.getPropertyList().isEmpty()) {
throw new BusinessException("连接id:" + runId + "电文号:" + msgKeyName + "属性列表为空");
}
//返回点位信息
return dto.getPropertyList();
}
@Override
public void onRead(Object message) {
//获取表检仪上送或返回消息
ByteBuf inBuf = (ByteBuf) message;
int length = inBuf.readableBytes();
//将消息头和消息体拆包,解析出消息头信息
SurfaceVisionFrameInputVo vo = SurfaceVisionVoDecoder.Decode(inBuf);
logger.info("AMETEKSurfaceVision收到 msg: {}", vo);
//消息头,也是电文信息
String msgKey = vo.getMsgKey();
try {
//通过消息头判断返回消息类型
if(vo.getBeatType()){
//判断是否心跳信息
lastAliveTime = System.currentTimeMillis();
logger.info("接收到心跳消息,当前时间为:{}", lastAliveTime);
} else if (msgKey.startsWith(SurfaceVisionConstants.RETURN_HEADER1)) {
//非Query命令正常返回消息
//解码
SurfaceVisionVoDecoder.DecodeReturn(vo);
//组装返回信息判断replayId是否一致
ExeResultVo sendResult = new ExeResultVo();
if (!currentCount.equals(vo.getReplayId())) {
logger.info("AMETEKSurfaceVision收到 msgkey: {} 消息:{}, ReplayId{} 与实际发送下去的:{},不一致"
, msgKey, vo, vo.getReplayId(), currentCount);
sendResult.setSuccess(false);
sendResult.setMessage("返回消息replayId与发送消息replayId不符");
} else {
sendResult.setSuccess(vo.getStatus());
sendResult.setMessage(vo.getDescription());
}
//组装返回结果
returnData(sendResult);
} else if (SurfaceVisionConstants.RETURN_HEADER2.equals(msgKey)) {
//下发命令异常返回消息
//解码
SurfaceVisionVoDecoder.DecodeReturnError(vo);
ExeResultVo sendResult = new ExeResultVo();
sendResult.setSuccess(vo.getStatus());
sendResult.setMessage(vo.getDescription());
//组装返回结果
returnData(sendResult);
} else if (SurfaceVisionConstants.RETURN_HEADER3.equals(msgKey)) {
//Query命令返回
//解码
SurfaceVisionVoDecoder.DecodeReturnQuery(vo);
ExeResultVo sendResult = new ExeResultVo();
sendResult.setSuccess(vo.getStatus());
sendResult.setMessage(vo.getDescription());
Map<Object, Object> queryData = new HashMap<>();
queryData.putAll(vo.getReturnData());
sendResult.setData(queryData);
//组装返回结果
returnData(sendResult);
} else {
//主动上报消息
//解码
SurfaceVisionVoDecoder.DecodeData(vo, getPropertyConfig(msgKey));
Map<String, Object> realDataMap = vo.getReturnData();
//数据发送到平台
if (vo != null && serviceProvider != null && socketGateway != null) {
SendService service = (SendService) serviceProvider.getByName(ServiceName.Send);
//组装数据包
SocketMessage socketMessage = socketGateway.buildSocketMessage();
socketMessage.setDeviceId(deviceId);
socketMessage.getPropsMap().put(SurfaceVisionConstants.S_V_SEND_PLATFORM_DATA, realDataMap);
socketMessage.setMsgKey(msgKey);
//发送数据
service.sendMessage(socketMessage);
} else {
logger.info("AMETEKSurfaceVision收到 msgkey: {} 消息:{}, 但是不能发到平台", msgKey, JSON.toJSONString(realDataMap));
}
}
}catch (Exception e){
logger.error("AMETEKSurfaceVision接收消息匹配错误, msgKey: {}, msg:{}, error", msgKey, vo, e);
}
if(socketGateway!= null && Boolean.TRUE.equals(socketGateway.getInstanceVo().getLogOpen())) {
logger.info("AMETEKSurfaceVision {} 报文长度:{} vo:{} ", getChannel(), length, JSON.toJSONString(vo));
}
}
/** 设置当前下发命令返回信息 */
private void returnData(ExeResultVo sendResult) {
if(currentSend == null){
throw new BusinessException("下发返回消息没有对应的下发命令");
}
currentSend.setRealData(sendResult);
currentSend.setSendReturnFlag(true);
currentSend = null;
}
@Override
public void onOpen() {
super.onOpen();
logger.info("建立连接channel:{}", getChannel());
}
@Override
public void onClose() {
super.onClose();
}
public void close() {
if(getChannel() != null) {
try {
getChannel().close().sync();
} catch (InterruptedException e) {
logger.warn(e.getLocalizedMessage(), e);
}
}
}
public String gwPrefix() {
if(gwPrefixCache != null) {
return gwPrefixCache;
}
gwPrefixCache = "";
if(socketGateway != null && socketGateway.getInstanceVo() != null) {
gwPrefixCache = "网关Id:" + socketGateway.getInstanceVo().getRunId() + "连接:" + getChannel() + " ";
}else {
gwPrefixCache = "连接:" + getChannel() + " ";
}
return gwPrefixCache;
}
public long getLastAliveTime() {
return lastAliveTime;
}
@Override
public void send(Object message) {
//下发命令
SurfaceVisionSocketReturnMessage returnMsg = (SurfaceVisionSocketReturnMessage) message;
String msgKey = returnMsg.getMsgKey();
//与AMETEKSurfaceVisionSocketProtocol类对应
Map<String, Object> propsMap = (Map<String, Object>)
returnMsg.getPropsMap().get(SurfaceVisionConstants.S_V_SEND_DATA);
//获取下发点位配置
List<PropertyConfig> propertyConfigList = getPropertyConfig(msgKey);
//获取计数器值作为下发命令replayId
int c = getCount();
logger.info("下发数据, 数据:{}, 点位配置:{}, 返回ID:{}", propsMap, propertyConfigList, c);
ByteBuf byteBuf = SurfaceVisionEncoder.Encode(msgKey, propsMap, propertyConfigList, c);
logger.info("下发数据的byteBuf:{}", byteBuf);
//下发命令编码后发送
getChannel().writeAndFlush(byteBuf);
logger.info("下发数据成功");
//缓存当前下发命令信息和replayId
currentSend = returnMsg;
currentCount = c;
//计数器自增
increment();
}
public void sendBeat() {
logger.info("发送心跳");
ByteBuf byteBuf = Unpooled.wrappedBuffer(beat);
getChannel().writeAndFlush(byteBuf);
logger.info("心跳发送成功");
}
}