/** * 触发超时事件 * * @param p */ private void fireOperationTimeOutEvent(OutPacket packet, String portName) { ErrorPacket error = new ErrorPacket(ErrorPacket.ERROR_TIMEOUT, client.getUser()); error.timeoutPacket = packet; error.setHeader(packet.getHeader()); error.setFamily(packet.getFamily()); client.addIncomingPacket(error, portName); }
/* (non-Javadoc) * @see edu.tsinghua.lumaqq.qq.net.IPort#send(edu.tsinghua.lumaqq.qq.packets.OutPacket) */ public void send(OutPacket packet) { try { sendBuf.clear(); packet.fill(sendBuf); sendBuf.flip(); if (packet.needAck()) { channel.write(sendBuf); log.debug("已发送 - " + packet.toString()); } else { int count = packet.getSendCount(); for (int i = 0; i < count; i++) { sendBuf.rewind(); channel.write(sendBuf); log.debug("已发送 - " + packet.toString()); } } } catch (Exception e) { log.error(e.getMessage()); } }
/* (non-Javadoc) * @see java.util.concurrent.Callable#call() */ public T call() throws Exception { long t = getTimeoutLeft(); while (t <= 0) { OutPacket packet = remove(); // 发送 IConnection port = client.getConnection(portName); if (port != null && packet != null && !port.getPolicy().isReplied(packet, false)) { if (packet.needResend()) { // 重发次数未到最大,重发 client.sendPacketAnyway(packet, portName); } else { // 触发操作超时事件 fireOperationTimeOutEvent(packet, portName); } } t = getTimeoutLeft(); } QQClient.executor.schedule(this, t, TimeUnit.MILLISECONDS); return null; }
/* (non-Javadoc) * @see edu.tsinghua.lumaqq.qq.IPort#send() */ public void send() throws IOException { while (!isEmpty()) { sendBuf.clear(); OutPacket packet = remove(); packet.fill(sendBuf); sendBuf.flip(); if (packet.needAck()) { channel.write(sendBuf); // 添加到重发队列 packet.setTimeout(System.currentTimeMillis() + QQ.QQ_TIMEOUT_SEND); policy.pushResend(packet, getId()); log.debug("已发送 - " + packet.toString()); } else { int count = packet.getSendCount(); for (int i = 0; i < count; i++) { sendBuf.rewind(); channel.write(sendBuf); log.debug("已发送 - " + packet.toString()); } } } }
/** * 得到下一个包的超时时间 * * @return 下一个包的超时时间,如果队列为空,返回一个固定值 */ private long getTimeoutLeft() { OutPacket packet = get(); if (packet == null) return QQ.QQ_TIMEOUT_SEND; else return packet.getTimeout() - System.currentTimeMillis(); }