Hi all,

In the interest of explaining myself further and also considering a server 
scenario, i think it would be useful to be able to preserve the address 
information extracted from a DatagramPacket, where in a server application, 
it would be possible to use the address information from a request to send 
a response to a client.  I'd like to use the AddressedEnvelope to avoid 
polluting all message types with the address information.  To avoid having 
to write multiple handlers that would handle an AddressedEnvelope type for 
each of my messages, i think a generic message to message handler which 
handles AddressedEnvelopes and delegates to a provided message to message 
encoder/decoders would be useful.  Here is a snippet of what i mean ( 
"inspired" by DatagramPacketEncoder/Decoder)

public class AddressedEnvelopeMessageToMessageEncoder<M, T>
        extends MessageToMessageEncoder<AddressedEnvelope<M, 
InetSocketAddress>> {

    private final MessageToMessageEncoder<? super M> encoder;
    private final Class<T> resultClazz;

    /**
     * Create an encoder that encodes the content in {@link 
AddressedEnvelope}
     * to {@link AddressedEnvelope} using the specified message encoder.
     *
     * @param encoder
     *            the specified message encoder
     */
    public 
AddressedEnvelopeMessageToMessageEncoder(MessageToMessageEncoder<? super M> 
encoder,
            Class<T> resultClazz) {
        this.encoder = checkNotNull(encoder, "encoder");
        this.resultClazz = checkNotNull(resultClazz, "resultClazz");
    }

    @Override
    public boolean acceptOutboundMessage(Object msg) throws Exception {
        if (super.acceptOutboundMessage(msg)) {
            @SuppressWarnings("rawtypes")
            AddressedEnvelope envelope = (AddressedEnvelope) msg;
            return encoder.acceptOutboundMessage(envelope.content()) && 
envelope.sender() instanceof InetSocketAddress
                    && envelope.recipient() instanceof InetSocketAddress;
        }
        return false;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, AddressedEnvelope<M, 
InetSocketAddress> msg, List<Object> out)
            throws Exception {
        assert out.isEmpty();

        encoder.encode(ctx, msg.content(), out);
        if (out.size() != 1) {
            throw new EncoderException(StringUtil.simpleClassName(encoder) 
+ " must produce only one message.");
        }
        Object content = out.get(0);
        if (resultClazz.isInstance(content)) {
            // Replace the T with an AddressedEnvelope<T, 
InetSocketAddress>.
            out.set(0, new DefaultAddressedEnvelope<T, 
InetSocketAddress>(resultClazz.cast(content), msg.recipient(),
                    msg.sender()));
        } else {
            throw new EncoderException(
                    StringUtil.simpleClassName(encoder) + " must produce 
only " + resultClazz.getSimpleName() + ".");
        }
    }

// ... methods removed for brevity

}

public class AddressedEnvelopeMessageToMessageDecoder<M, T>
        extends MessageToMessageDecoder<AddressedEnvelope<M, 
InetSocketAddress>> {

    private final MessageToMessageDecoder<M> decoder;
    private final Class<T> resultClazz;

    /**
     * Create a {@link DatagramPacket} decoder using the specified
     * {@link ByteBuf} decoder.
     *
     * @param decoder
     *            the specified {@link ByteBuf} decoder
     */
    public 
AddressedEnvelopeMessageToMessageDecoder(MessageToMessageDecoder<M> 
decoder, Class<T> resultClazz) {
        this.decoder = checkNotNull(decoder, "decoder");
        this.resultClazz = checkNotNull(resultClazz, "resultClazz");
    }

    @Override
    public boolean acceptInboundMessage(Object msg) throws Exception {
        if (msg instanceof AddressedEnvelope) {
            @SuppressWarnings("unchecked")
            AddressedEnvelope<M, InetSocketAddress> addressedEnvelope = 
(AddressedEnvelope<M, InetSocketAddress>) msg;
            return 
decoder.acceptInboundMessage(addressedEnvelope.content());
        }
        return false;
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, AddressedEnvelope<M, 
InetSocketAddress> msg, List<Object> out)
            throws Exception {
        decoder.decode(ctx, msg.content(), out);

        if (out.size() != 1) {
            throw new EncoderException(StringUtil.simpleClassName(decoder) 
+ " must produce only one message.");
        }
        Object content = out.get(0);
        if (resultClazz.isInstance(content)) {
            // Replace the T with an AddressedEnvelope<T, 
InetSocketAddress>.
            out.set(0, new DefaultAddressedEnvelope<T, 
InetSocketAddress>(resultClazz.cast(content), msg.recipient(),
                    msg.sender()));
        } else {
            throw new EncoderException(
                    StringUtil.simpleClassName(decoder) + " must produce 
only " + resultClazz.getSimpleName() + ".");
        }
    }
// .. methods removed for brevity
}

Regards,

Joe


-- 
You received this message because you are subscribed to the Google Groups 
"Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/e51dd9ca-01ae-4e49-a399-33f96a2ff057%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to