io.netty5.example.dns.udp.DnsClient is DNS client to lookup A record of domain "www.example.com" by UDP.
Setup io.netty5.channel.Channel instance
Please read the following code.
EventLoopGroup group = new MultithreadEventLoopGroup(NioHandler.newFactory()) Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .handler(new ChannelInitializer<DatagramChannel>() { @Override protected void initChannel(DatagramChannel ch) { ChannelPipeline p = ch.pipeline(); p.addLast(new DatagramDnsQueryEncoder()) .addLast(new DatagramDnsResponseDecoder()) .addLast(new SimpleChannelInboundHandler<DatagramDnsResponse>() { @Override protected void messageReceived(ChannelHandlerContext ctx, DatagramDnsResponse msg) { try { handleQueryResp(msg); } finally { ctx.close(); } } }); } });
- anything related to communication is executed in one of the threads of EventLoopGroup
- NioDatagramChannel.class states that the underlying network library is Java NIO DatagramChannel
- handler() accepts a subclass of io.netty5.channel.ChannelInitializer which implements the function initChannel(DatagramChannel). It is to setup list of ChannelHandler in ChannelPipeline. I called this class setup channel class
Channel instances will be built and obtained in the following.
final Channel ch = b.bind(0).asStage().get();
When bind(0) is called, io.netty5.bootstrap.Bootstrap#init is triggered.
@Override Future<Channel> init(Channel channel) { ChannelPipeline p = channel.pipeline(); setChannelOptions(channel, newOptionsArray(), logger); setAttributes(channel, newAttributesArray()); p.addLast(config.handler()); return channel.executor().newSucceededFuture(channel); }
Value of config.handler() is setup channel class. And then io.netty5.channel.ChannelInitializer#handlerAdded is triggered.
@Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { try { initChannel((C) ctx.channel()); } catch (Throwable cause) { // Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...). // We do so to prevent multiple calls to initChannel(...). channelExceptionCaught(ctx, cause); } finally { if (!ctx.isRemoved()) { ctx.pipeline().remove(this); } } }
Setup channel class will be removed after ChannelPipeline is setup. Then the following will be in ChannelPipeline
- DefaultChannelPipeline$HeadHandler
- DatagramDnsQueryEncoder
- DatagramDnsResponseDecoder
- subclass of SimpleChannelInboundHandler
- DefaultChannelPipeline$TailHandler
Top comments (0)