@Override public void run() { try { long now = System.currentTimeMillis(); synchronized (monitor) { // Send due empty acknowledgements Iterator<Map.Entry<Long, Collection<IncomingReliableMessageExchange>>> dueAcknowledgements = emptyAcknowledgementSchedule.asMap().headMap(now, true).entrySet().iterator(); while (dueAcknowledgements.hasNext()) { Map.Entry<Long, Collection<IncomingReliableMessageExchange>> part = dueAcknowledgements.next(); for (IncomingReliableMessageExchange messageExchange : part.getValue()) { if (!messageExchange.isAcknowledgementSent()) { InetSocketAddress remoteEndpoint = messageExchange.getRemoteEndpoint(); int messageID = messageExchange.getMessageID(); writeEmptyAcknowledgement(remoteEndpoint, messageID); messageExchange.setAcknowledgementSent(); } } dueAcknowledgements.remove(); } // Retire open NON messages } } catch (Exception e) { log.error("Error in reliability task for incoming message exchanges!", e); } }
private void handleOutgoingCoapResponse(ChannelHandlerContext ctx, MessageEvent me) { CoapResponse coapResponse = (CoapResponse) me.getMessage(); InetSocketAddress remoteEndpoint = (InetSocketAddress) me.getRemoteAddress(); IncomingMessageExchange messageExchange; synchronized (monitor) { messageExchange = ongoingMessageExchanges.remove(remoteEndpoint, coapResponse.getMessageID()); } if (messageExchange instanceof IncomingReliableMessageExchange) { // if the ongoing message exchange is reliable and the empty ACK was not yet sent make // response piggy- // backed and suppress scheduled empty ACK if (!((IncomingReliableMessageExchange) messageExchange).isAcknowledgementSent()) { coapResponse.setMessageType(MessageType.Name.ACK.getNumber()); ((IncomingReliableMessageExchange) messageExchange).setAcknowledgementSent(); } } ctx.sendDownstream(me); }