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 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)); } } }