}
@Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise)
throws Exception {
AlternativeCompositeByteBuf buf = null;
if (!(msg instanceof Message)) {
ctx.write(msg, promise);
return;
}
try {
boolean done = false;
if (preferDirect) {
buf = alloc.compDirectBuffer();
} else {
buf = alloc.compBuffer();
}
//null, means create signature
done = encoder.write(buf, (Message) msg, null);
final Message message = encoder.message();
if (buf.isReadable()) {
// this will release the buffer
if (ctx.channel() instanceof DatagramChannel) {
final InetSocketAddress recipientUnreflected;
final InetSocketAddress recipient;
final InetSocketAddress sender;
if (message.senderSocket() == null) {
//in case of a request
if(message.recipientRelay()!=null) {
//in case of sending to a relay (the relayed flag is already set)
recipientUnreflected = message.recipientRelay().createSocketUDP();
} else {
recipientUnreflected = message.recipient().createSocketUDP();
}
recipient = Utils.natReflection(recipientUnreflected, true, message.sender());
sender = message.sender().createSocketUDP(0);
} else {
//in case of a reply
recipient = message.senderSocket();
sender = message.recipientSocket();
}
DatagramPacket d = new DatagramPacket(buf, recipient, sender);
LOG.debug("Send UPD message {}, datagram: {}", message, d);
ctx.writeAndFlush(d, promise);
} else {
LOG.debug("Send TCP message {} to {}", message, message.senderSocket());
ctx.writeAndFlush(buf, promise);
}
if (done) {
message.setDone(true);
// we wrote the complete message, reset state
encoder.reset();
}
} else {
buf.release();
ctx.write(Unpooled.EMPTY_BUFFER, promise);
}
buf = null;
} catch (Throwable t) {
ctx.fireExceptionCaught(t);
}
finally {
if (buf != null) {
buf.release();
}
}
}