ModBus-rtcp/src/main/java/com/iot/modbus_rtcp/netty/ModbusDecoder.java

88 lines
3.7 KiB
Java

package com.iot.modbus_rtcp.netty;
import cn.hutool.core.util.ArrayUtil;
import com.iot.modbus_rtcp.config.EquipmentIPProperties;
import com.iot.modbus_rtcp.dto.ModbusCommandDto;
import com.iot.modbus_rtcp.utils.HexUtil;
import com.iot.modbus_rtcp.utils.SpringUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import java.net.InetSocketAddress;
import java.util.List;
@Slf4j
public class ModbusDecoder extends ByteToMessageDecoder {
private final ChannelGroup channelGroup;
private final EquipmentIPProperties equipmentIPProperties;
public ModbusDecoder(ChannelGroup channelGroup) {
this.channelGroup = channelGroup;
this.equipmentIPProperties = SpringUtil.getBean(EquipmentIPProperties.class);
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
String ip = ((InetSocketAddress) ctx.channel().remoteAddress()).getHostString();
int port = ((InetSocketAddress) ctx.channel().remoteAddress()).getPort();
byte[] b = new byte[buffer.readableBytes()];
buffer.readBytes(b);
String hex = HexUtil.bytesToHexString(b);
log.info("解析到:{}", hex);
if (this.equipmentIPProperties.contains(hex.toUpperCase())) { // 心跳
String msgUpperCase = hex.toUpperCase();
log.info("注册{}({}:{}):{}", this.equipmentIPProperties.get(msgUpperCase), ip, port, msgUpperCase);
String currentAddress = ChannelGroup.getKey(ip, port);
SyncPriorityChannel channel = this.channelGroup.get(currentAddress);
channel.setIdentifier(msgUpperCase);
this.channelGroup.put(msgUpperCase, channel);
SpringUtil.getBean(RabbitAdmin.class).declareQueue(QueueBuilder.durable(channel.getCollectQueue()).build());
IPGatewayRelation.put(currentAddress, String.format("%s(%s)", this.equipmentIPProperties.get(msgUpperCase), msgUpperCase));
String oldAddress = IPGatewayRelation.getIPAddress(msgUpperCase);
if (StringUtils.isNotBlank(currentAddress) &&
StringUtils.isNotBlank(oldAddress) &&
!currentAddress.equals(oldAddress)) {
//说明设备重连后IP+端口发生了改变
String[] split = oldAddress.split(":");
//删除老连接
this.channelGroup.remove(split[0], Integer.parseInt(split[1]));
log.info("删除channelGroup通道:{}连接:{},新增该通道连接:{}", this.equipmentIPProperties.get(msgUpperCase), oldAddress, currentAddress);
}
IPGatewayRelation.putIPAddressMap(msgUpperCase, currentAddress);
return;
}
SyncPriorityChannel channel = this.channelGroup.get(ip, port);
ModbusCommandDto message = channel.getCurrentMessage();
if (message == null) {
log.warn("非法传输:{}", HexUtil.bytesToHexString(b));
return;
}
String identity = ChannelGroup.getKey(ip, port);
byte[] bytesCache = DataCache.get(identity);
if (bytesCache == null) {
bytesCache = b;
} else {
bytesCache = ArrayUtil.addAll(bytesCache, b);
}
if (bytesCache.length < (message.getLength() / 2)) {
DataCache.put(identity, bytesCache);
} else if (bytesCache.length == (message.getLength() / 2)) {
out.add(HexUtil.bytesToHexString(bytesCache));
}
}
}