MesClientHandler.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package com.mes.tcp;
  2. import io.netty.channel.Channel;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. /**
  8. * MES客户端消息处理器
  9. * 接收服务端响应,解析后分发到对应工位
  10. */
  11. public class MesClientHandler extends ChannelInboundHandlerAdapter {
  12. private static final Logger log = LoggerFactory.getLogger(MesClientHandler.class);
  13. private final MesTcpClient tcpClient;
  14. private final MessageDispatcher dispatcher;
  15. public MesClientHandler(MesTcpClient tcpClient, MessageDispatcher dispatcher) {
  16. this.tcpClient = tcpClient;
  17. this.dispatcher = dispatcher;
  18. }
  19. @Override
  20. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  21. log.info("TCP连接已建立: {}", ctx.channel().remoteAddress());
  22. }
  23. @Override
  24. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  25. log.info("TCP连接已断开");
  26. if (tcpClient != null) {
  27. tcpClient.onDisconnected();
  28. }
  29. }
  30. @Override
  31. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  32. String rawMessage = msg.toString();
  33. log.info("==============================================================================");
  34. log.info("| TCP返回报文内容: {}", rawMessage);
  35. // 格式化消息(移除前缀等)
  36. String mesMessage = formatResult(rawMessage);
  37. if (mesMessage.isEmpty()) {
  38. log.info("| TCP返回报文内容格式错误, 弃用!");
  39. log.info("==============================================================================");
  40. return;
  41. }
  42. // 解析消息类型
  43. String msgType = getMsgType(mesMessage);
  44. log.info("| TCP返回报文类型: {}", msgType);
  45. // 解析结果码
  46. String result = getResult(mesMessage);
  47. log.info("| TCP返回报文结果: {}", result);
  48. // 解析工位号
  49. String stationCode = getStationCode(mesMessage);
  50. log.info("| TCP返回工位号: {}", stationCode);
  51. log.info("==============================================================================");
  52. // 分发消息
  53. if (dispatcher != null && stationCode != null) {
  54. dispatcher.dispatch(stationCode, msgType, result, mesMessage);
  55. }
  56. }
  57. @Override
  58. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  59. log.error("TCP通信异常: {}", cause.getMessage());
  60. ctx.close();
  61. }
  62. /**
  63. * 格式化消息(移除状态前缀)
  64. */
  65. private String formatResult(String msg) {
  66. if (msg == null || msg.length() < 3) {
  67. return "";
  68. }
  69. String prefix = msg.substring(0, 2).trim();
  70. if ("OK".equals(prefix)) {
  71. return msg.substring(3);
  72. }
  73. return "";
  74. }
  75. /**
  76. * 获取消息类型
  77. * 消息格式: aaaabbbbbABW[MSGTYPE]GW...
  78. * 消息类型位于位置12-16
  79. */
  80. private String getMsgType(String msg) {
  81. if (msg.length() < 16) {
  82. return "";
  83. }
  84. return msg.substring(12, 16);
  85. }
  86. /**
  87. * 获取工位号
  88. * 工位号位于固定位置18-26(v2 协议 oprno 扩到 8 字符)
  89. */
  90. private String getStationCode(String msg) {
  91. // 固定位置解析
  92. if (msg.length() >= 26) {
  93. return msg.substring(18, 26).trim();
  94. }
  95. // 备用方案:查找GW字段
  96. int gwIndex = msg.indexOf("GW");
  97. if (gwIndex >= 0 && msg.length() >= gwIndex + 10) {
  98. return msg.substring(gwIndex + 2, gwIndex + 10).trim();
  99. }
  100. return null;
  101. }
  102. /**
  103. * 获取结果码。
  104. * - v2 协议报文(长度 98):位置 74-76
  105. * - v3 协议报文(AQDW/MQDW,长度 99):lx 从 2 位扩到 3 位,result 后移 1,位置 75-77
  106. */
  107. private String getResult(String msg) {
  108. String msgType = getMsgType(msg);
  109. // v3 扩展报文
  110. if ("AQDW".equals(msgType) || "MQDW".equals(msgType)) {
  111. if (msg.length() >= 77) {
  112. return msg.substring(75, 77).trim();
  113. }
  114. } else {
  115. // v2 或其他报文
  116. if (msg.length() >= 76) {
  117. return msg.substring(74, 76).trim();
  118. }
  119. }
  120. // 备用方案:查找 RS 字段
  121. int rsIndex = msg.indexOf("RS");
  122. if (rsIndex >= 0 && msg.length() >= rsIndex + 4) {
  123. return msg.substring(rsIndex + 2, rsIndex + 4).trim();
  124. }
  125. return "";
  126. }
  127. }