GatherProtocolHandler.java 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package com.hb.proj.gather.test;
  2. import java.util.Arrays;
  3. import java.util.List;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import com.hb.proj.gather.protocol.ChannelGroupMgr;
  7. import com.hb.proj.gather.protocol.GatherRespParser;
  8. import com.hb.proj.gather.utils.ByteUtils;
  9. import com.hb.proj.gather.utils.Crc16Utils;
  10. import io.netty.channel.ChannelHandlerContext;
  11. import io.netty.channel.ChannelInboundHandlerAdapter;
  12. public class GatherProtocolHandler extends ChannelInboundHandlerAdapter {
  13. private final static Logger logger = LoggerFactory.getLogger(GatherProtocolHandler.class);
  14. @Override
  15. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  16. //msg:如果设置了decoder编码器,则msg为编码后的类型,可强制转换
  17. byte[] recmsg=(byte[])msg;
  18. String hexmsg=ByteUtils.toHexString(recmsg);
  19. //两字节且不以0103开头,就认为是心跳数据-作为设备号,该方法并不可靠,有可能把采集的残包数据当作心跳
  20. if(recmsg.length==2&&(!hexmsg.startsWith("0103"))) {
  21. if(!ChannelGroupMgr.contains(ctx.channel())) {
  22. ChannelGroupMgr.add(ctx.channel(),ByteUtils.toIntStr(recmsg));
  23. }
  24. }
  25. else if(hexmsg.startsWith("0103")){ //采集指令返回数据
  26. int datalen=recmsg[2]&0xff; //数据区字节数
  27. logger.info("数据字节长度:{}",datalen);
  28. byte[] hdBodyMsg=Arrays.copyOfRange(recmsg,0,datalen+3); //除CRC外的消息主体
  29. byte[] crc16=Arrays.copyOfRange(recmsg,datalen+3,datalen+3+2); //2字节校验位
  30. //System.arraycopy(recmsg,0,hdBodyMsg,0,hdBodyMsg.length);
  31. //System.arraycopy(recmsg,hdBodyMsg.length,crc16,0,crc16.length);
  32. int calCrc16=Crc16Utils.getCRC(hdBodyMsg);
  33. logger.info("接收CRC:{}:{},计算CRC:{}",ByteUtils.toHexString(crc16),ByteUtils.byte2ToIntHL(crc16),calCrc16);
  34. if(ByteUtils.byte2ToIntHL(crc16)==calCrc16) { //crc校验通过
  35. //List<Integer> smpdatas=GatherRespParser.parseFloat(Arrays.copyOfRange(hdBodyMsg,3,datalen+3), 4);
  36. //logger.info("解析后的采集数据{}",smpdatas);
  37. }
  38. }
  39. ctx.fireChannelRead(msg);
  40. }
  41. }