88 lines
3.7 KiB
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));
|
|
}
|
|
}
|
|
|
|
}
|