@Override public void run() { while (!stop) { // 业务逻辑 try { // 这里做流量控制 TpsTool.limitTPS(); // 取包发送 APackage pack = this.doSubmit(); if (pack == null) { pack = buffer.poll(); } if (pack == null) { // 确认是否需要发送链路检测包 long curTime = System.currentTimeMillis(); if (curTime > (lastActiveTime + timeout)) { if (channel.isLogin()) { // 链路已经空闲超过60s,且连接还未断开,需要发送UnbindMessage包 log.info("链路空闲超过" + timeout + "ms,发送UnbindMessage包断开连接"); channel.unbind(); } } } if (pack == null) { continue; } // 设置发送时间 lastActiveTime = System.currentTimeMillis(); try { boolean flag = sendPacket(pack); if (!flag) { buffer.offer(pack); } } catch (IOException ex) { // 发送失败重发 log.error(null, ex); if (pack.getTryTimes() < retryTimes) { buffer.offer(pack); } else { // 记录丢失的包到文件中 discard.info( "丢失包,重试多次失败" + pack.getHead().getCommandIdString() + ",字节码:" + Hex.rhex(pack.getBytes())); } } } catch (Exception ex) { log.error(null, ex); // 发生异常,强制关闭连接 channel.close(); } } }
/** * 发送包,该方法是同步的 * * @param pack 可能是submit报或者unbind包 包 * @return 如果通道不可用 返回false 发送成功返回true * @throws IOException * @throws IOException */ private boolean sendPacket(APackage pack) throws IOException { log.info("发送SubmitMessage包:" + pack); APackage recv = channel.send(pack); log.info("收到SubmitRespMessage包:" + recv); if (recv == null) { return false; } // 对收到的包记录二进制信息 if ((pack instanceof SubmitMessage) && (recv instanceof SubmitRespMessage)) { doSubmitResp((SubmitMessage) pack, (SubmitRespMessage) recv); return true; } else { log.error("发送包和接受包都有误:" + pack + recv); return false; } }