Hi Norman,

Apologies for the late response.  The encoders in my example above were in 
the wrong order which prevented the handlers from being invoked.

To briefly summarise my use case :

Type2 -> Type1 -> Outbound

I ended up with something similar to the following code snippets:


ChannelInitializer<DatagramChannel> datagramChannelInitializer = new 
ChannelInitializer<DatagramChannel>() {
                    @Override
                    public void initChannel(DatagramChannel ch) throws 
Exception {


                                ch.pipeline().addLast(new 
DatagramPacketDecoder(new Type1Decoder()))
                                .addLast(new Type2MessageToMessageDecoder())
                                .addLast(new DatagramPacketEncoder<>(new 
Type1Encoder())
                                .addLast(new 
AddressEnvelopeType2MessageToMessageEncoder()));
                    }
}


    
public class UdpClient{


 private final SocketAddress socketAddress
 private Bootstrap bootstrap;
 private Channel channel;


 public UdpClient(SocketAddress socketAddress)
 {
 this.socketAddress = socketAddress;
 this.bootstrap = new Bootstrap();
 this.bootstrap.handler(channelInitializer);
 }


    public void write(Type2 message, boolean await) {
        AddressedEnvelope<Type2, SocketAddress> addressedEnvelope = new 
DefaultAddressedEnvelope<Type2, SocketAddress>(message,
                socketAddress, channel.localAddress());
        if (await) {
            channel.writeAndFlush(addressedEnvelope).awaitUninterruptibly();
        } else {
            channel.writeAndFlush(addressedEnvelope, channel.voidPromise());
        }
    }
}


public class AddressEnvelopeType2MessageToMessageEncoder
        extends MessageToMessageEncoder<AddressedEnvelope<Type2, 
SocketAddress>> {


    @Override
    protected void encode(ChannelHandlerContext ctx, AddressedEnvelope<
Type2Message, SocketAddress> envelope,
            List<Object> out) throws Exception {
        out.add(new DefaultAddressedEnvelope<Type1, SocketAddress>(
                new Type1(envelope.content().getParameter()),
                envelope.recipient(), envelope.sender()));
    }


}


The UdpClient class is instantiated with the socketAddress of the remote 
server.  If I'd like to reuse the Netty AddressedEnvelope for addressing 
purposes and also transform the message using a 
MessageToMessageEncoder/Decoder in the channel pipeline, I have to create a 
MessageToMessageEncoder similar to the one above.

Is there a better way of doing this?

Since it's possible to put multiple MessageToMessage encoder/decoders on 
the same channel pipeline It would be nice to be able to preserve the 
Address information along the pipeline for the UDP use case.  I attempted 
to create a generic MessageToMessageEncoder that would do this similar in 
nature to the DatagramPacketEncoder which would delegate to a provided 
encoder.  I didn't have alot of time in the end so opted for the approach 
above.

Cheers,

Joe



On Thursday, 4 August 2016 14:11:36 UTC+1, Joseph Madden wrote:
>
> Hi,
>
> I'd like to use a MessageToMessageDecoder to transform from one type to 
> another while sending a message from a client to a remote server.  The 
> MessageToMessage Encoder/Decoder allow this to be accomplished easily. 
>  When using UDP and an AddressedEnvelope to preserve remote address info, 
> this is not the case.  
>
> The following snippet shows a simplified channel pipeline to hopefully 
> illustrate my use case.
>
> ChannelInitializer<DatagramChannel> datagramChannelInitializer = new 
> ChannelInitializer<DatagramChannel>() {
>                     @Override
>                     public void initChannel(DatagramChannel ch) throws 
> Exception {
>
>                                 ch.pipeline().addLast(new 
> DatagramPacketDecoder(new Type1Decoder()))
>                                 .addLast(new 
> Type2MessageToMessageDecoder())
>                                 .addLast(new 
> Type2MessageToMessageEncoder())
>                                 .addLast(new DatagramPacketEncoder<>(new 
> Type1Encoder()));
>                     }
> }
>
>
> During encoding, I wrap my type1 payload in an AddressedEnvelope to 
> specify the remote address.  The Type2MessageToMessageEncoder is never 
> invoked because AddressedEnvelope<Type1, SocketAddress> does not match 
> Type2.  I tried to create my own class 
> AddressedEnvelopeMessageToMessageEncoder similar to the 
> DatagramPacketEncoder which delegates to a provided encoder but the encode 
> method is not visible.
>
> What is the recommended approach for this kind of use case?  Any help 
> appreciated.
>
> Thanks,
>
> 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/70b8f49e-083a-40da-b925-6513a355f4ae%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to