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()));
}
}
--
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 netty+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netty/788b5d49-63fa-4dff-b522-81d90118ada3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi Norman,Apologies for not getting back to you sooner. My initial attempt at this had a bug in it. I had the encoders in the wrong order. I ended up with something like this:
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 Type2MessageToMessageEncoder())
);
}
}
On Thursday, 4 August 2016 14:13:19 UTC+1, Norman Maurer wrote:Can you show me the code that not worked ?On 02 Aug 2016, at 15:06, madde...@gmail.com 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>() {@Overridepublic void initChannel(DatagramChannel ch) throws Exception {ch.pipeline().addLast(new DatagramPacketDecoder(new Type1Decoder())).addLast(new Type2MessageToMessageDecoder())
--
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 netty+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netty/78f3bafd-ba4b-4b97-8cea-0725e89a3c6d%40googlegroups.com.
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()));
}
}
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}