@Override
public FutureDone<Message> forwardToUnreachable(final Message message) {
// Send message via direct message through the open connection to the unreachable peer
LOG.debug("Sending {} to unreachable peer {}", message, peerConnection.remotePeer());
final Message envelope = createMessage(peerConnection.remotePeer(), RPC.Commands.RELAY.getNr(), Type.REQUEST_2);
try {
message.restoreContentReferences();
// add the message into the payload
envelope.buffer(RelayUtils.encodeMessage(message, connectionBean().channelServer().channelServerConfiguration().signatureFactory()));
} catch (Exception e) {
LOG.error("Cannot encode the message", e);
return new FutureDone<Message>().failed(e);
}
// always keep the connection open
envelope.keepAlive(true);
// this will be read RelayRPC.handlePiggyBackMessage
Collection<PeerSocketAddress> peerSocketAddresses = new ArrayList<PeerSocketAddress>(1);
peerSocketAddresses.add(new PeerSocketAddress(message.sender().inetAddress(), 0, 0));
envelope.peerSocketAddresses(peerSocketAddresses);
// holds the message that will be returned to he requester
final FutureDone<Message> futureDone = new FutureDone<Message>();
// Forward a message through the open peer connection to the unreachable peer.
FutureResponse fr = RelayUtils.send(peerConnection, peerBean(), connectionBean(), config, envelope);
fr.addListener(new BaseFutureAdapter<FutureResponse>() {
public void operationComplete(FutureResponse future) throws Exception {
if (future.isSuccess()) {
InetSocketAddress senderSocket = message.recipientSocket();
if (senderSocket == null) {
senderSocket = unreachablePeerAddress().createSocketTCP();
}
InetSocketAddress recipientSocket = message.senderSocket();
if (recipientSocket == null) {
recipientSocket = message.sender().createSocketTCP();
}
Buffer buffer = future.responseMessage().buffer(0);
Message responseFromUnreachablePeer = RelayUtils.decodeMessage(buffer, recipientSocket, senderSocket, connectionBean().channelServer().channelServerConfiguration().signatureFactory());
responseFromUnreachablePeer.restoreContentReferences();
futureDone.done(responseFromUnreachablePeer);
} else {
futureDone.failed("Could not forward message over TCP channel");
}
}