DOCX

From the netty - example analysis netty component

By Katie Rice,2015-12-04 15:04
13 views 0
From the netty - example analysis netty component

    From the netty - example analysis netty component Analysis of nettystarting from the source

    Preparation:

    1. Download the source: https://github.com/netty/netty.git I download version 4.1

    2. The eclipse import maven project.

    Netty provides a netty - example project,

    Our analysis from here, netty is in the form of the client - server, we begin with the

    simplest example the discard the server-side code is as follows:

/**

     * Discards any incoming data.

     */

    public final class DiscardServer {

     static final boolean SSL = System.getProperty("ssl") != null ;

     static final int PORT = Integer.parseInt(System.getProperty("port", "8009" ));

     public static void main(String[] args) throws Exception {

     // Configure SSL.

     final SslContext sslCtx;

     if (SSL) {

     SelfSignedCertificate ssc = new SelfSignedCertificate();

     sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();

     } else {

     sslCtx = null ;

     }

     EventLoopGroup bossGroup = new NioEventLoopGroup(1 );

     EventLoopGroup workerGroup = new NioEventLoopGroup();

     try {

     ServerBootstrap b = new ServerBootstrap();

     b.group(bossGroup, workerGroup)

     .channel(NioServerSocketChannel. class )

     .handler( new LoggingHandler(LogLevel.INFO))

     .childHandler( new ChannelInitializer () {

     @Override

     public void initChannel(SocketChannel ch) {

     ChannelPipeline p = ch.pipeline();

     if (sslCtx != null ) {

     p.addLast(sslCtx.newHandler(ch.alloc()));

     }

     p.addLast( new DiscardServerHandler());

     }

     });

     // Bind and start to accept incoming connections.

     ChannelFuture f = b.bind(PORT).sync();

     // Wait until the server socket is closed.

     // In this example, this does not happen, but you can do that to gracefully

     // shut down your server.

     f.channel().closeFuture().sync();

     } finally {

     workerGroup.shutdownGracefully();

     bossGroup.shutdownGracefully();

     }

     }

    }

    The code above USES the following categories:

    1. EventLoopGroup

    The implementation class for NioEventLoopGroup, its hierarchy is:

    EventExecutorGroup for all class parent interface, it through the next () method to provide EventExecutor for use.In addition, it is also responsible for handling their life cycle, allowing close in elegant way.

    EventExecutor is a special kind of EventExcutorGroup, it provides some convenient way to check whether a thread is carried out in an event loop, in addition, it also expands the EventExecutorGroup, thus provides a general way of access method.

    EventLoopGroup is a special kind of EventExcutorGroup, it provides a registration function of the channel, the channel will be in event loop at the back of the selection to get to.

    NioEventLoopGroup inherited from MultithreadEventLoopGroup, based on the channel of NIO selector that will use this class.

    2. ServerBootstrap ServerChannel easily bootstrap.

    Group (EventLoopGroup parentGroup, EventLoopGroup childGroup) method to set the parent EventLoopGroup EventLoopGroup and sons.These EventLoopGroup used to handle all events and ServerChannel and IO Channel.

    Channel (Class extends C channelClass) method is used to create a channel instance.Create instances or using this method, the Channel if the Channel implementation is no structure or can use the channelFactory to create refs.

    Handler (ChannelHandler handler) method, ChannelHandler used to handle the request.

    ChildHandler (ChannelHandler childHandler) method, set ChannelHandler used to handle the request.

    3. A special ChannelInboundHandler ChannelInitializer

    When the Channel is registered to its eventLoop, ChannelInitializer initialization provides a convenient Channel of the method.The realization of the class is often used to set the channel of ChannelPipeline, usually used in Bootstrap# handler (ChannelHandler), ServerBootstrap# handler (ChannelHandler) and ServerBootstrap# childHandler (ChannelHandler) three scenarios.Example:

public class MyChannelInitializer extends ChannelInitializer{

     public void initChannel({@link Channel} channel) {

     channel.pipeline().addLast( "myHandler", new MyHandler());

     }

     }

    And then:

ServerBootstrap bootstrap = ...;

    ...

    bootstrap.childHandler( new MyChannelInitializer());

    Note: this class labeled can be Shared, so implementation class reuse is safe when necessary.

    4. The ChannelPipeline

    Understand the ChannelPipeline need to understand first ChannelHandler,

    4.1 ChannelHandler

    Handling an IO events or translating an IO operation, and transfer to ChannelPineline the next handler.

    You can use ChannelHandlerAdapter to replace it

    Because the interface has many interfaces need to implement, so you can only achieve ChannelHandlerAdapter to replace implements this interface.

    The Context object

    ChannelHandlerContext encapsulates the ChannelHandler.ChannelHandler should interact through the context object and the ChannelPipeLine it belongs.By using the context object, ChannelHandler can pass upward or downward, or dynamically modify the pipeline, or store the information of particular handler (use AttributeKey).

    State management

    A channelHandler usually need to store some state information.The simplest the most recommended way is to use member variables:

public interface Message {

     // your methods here

     }

     public class DataServerHandler extends SimpleChannelInboundHandler {

     private boolean loggedIn;

     {@code @Override}

     protected void messageReceived( ChannelHandlerContext ctx, Message message) {

     Channel ch = e.getChannel();

     if (message instanceof LoginMessage) {

     authenticate((LoginMessage) message);

     loggedIn = true ;

     } else (message instanceof GetDataMessage) {

     if (loggedIn) {

     ch.write(fetchSecret((GetDataMessage) message));

     } else {

     fail();

     }

     }

     }

     ...

     }

    Note: the state of the handler attached to the ChannePipelineContext, so you can add the

    same handler instance to different pipeline:

    public class DataServerInitializer extends ChannelInitializer {

     private static final DataServerHandler SHARED = new DataServerHandler();

     @Override

     public void initChannel(Channel channel) {

     channel.pipeline().addLast( "handler" , SHARED);

     }

     }

    @ Sharable annotations

    In the above example, USES a AttributeKey, you may notice @ Sharable annotation.

    If a ChannelHandler using @ sharable annotations, that means you just created a handler, you can add to one or more of the ChannelPipeline for many times without competition.

    If you don't specify the annotation, you must create a new handler instance each time, and increase to a ChannelPipeline, because it does not like member variables, it has a non-shared state.

    4.2 ChannelPipeline

    ChanelPipeline is a set of ChanelHandler, it handles or resolve the Inbound and OutBound event Channel operation.The realization of the ChannelPipeline isIntercepting FilterA senior form, so that users can control how to deal with events, a pipeline internal ChannelHandler interact.

    Pipeline incident process

    Above describes how the IO event was a ChannelPipeline ChannelHandler

    processing.An IO events are a ChannelInBoundHandler processing or

    ChannelOutboundHandler, then by calling the defined in ChannelHandlerContext event propagation method is passed to the handler, recent transmission method has ChannelHandlerContext# filreChannelRead (Object) and ChannelHandlerContext# write (Object).

    A the Inbound event is usually by the Inbound handler to deal with, such as such as the upper left.A the Inbound handler usually handle the Inbound data produced in IO thread at the bottom of the above.The Inbound data input in real operation such as SocketChannel# read (ByteBuffer) to obtain.If one of the inbound events over the top of the inbound handler, the event will be abandoned to not inform you or if you need to pay attention to, print out the logs.

    An outbound event by above the lower right of the outbound handler to deal with.An outbound handler is usually generated by the outbound flow such as write requests or shift.If

    an outbound event over the outbound at the bottom of the handler, it will be by the channel correlation IO thread processing.IO threads run normally is real output operations such as SocketChannel# write (byteBuffer).

    Example, suppose that we create the following such a pipeline.

ChannelPipeline} p = ...;

     p.addLast( "1", new InboundHandlerA());

     p.addLast( "2", new InboundHandlerB());

     p.addLast( "3", new OutboundHandlerA());

     p.addLast( "4", new OutboundHandlerB());

     p.addLast( "5", new InboundOutboundHandlerX());

    In the example above, of the handler at thestart of the inbound means it is a the inbound handler.Outbound at the beginning of handler means it is an outbound handler.Above example configuration when an event handler when entering the inbound order is 1, 2, 3, 4, 5;Handler when an event into the outbound order is 5,4,3,2,1. Under the supreme principle, the ChannelPipeline skip particular handler to shorten the processing of the depth of the stack:

    3, 4 does not implement ChannelInboundHandler, thus a,2,5 the inbound event processing order is 1.

    1, 2 don't implement ChannelOutBoundhandler and an outbound event processing order is 5, 3

    If 5 implements ChannelInboundHandler and channelOutBoundHandler at the same time, a the inbound and outbound event execution order is 125 and 543 respectively.

    An event to jump to the next handler

    As shown in the above, a handler triggered ChannelHandlerContext the event propagation method, and then passed on to the next handler.These methods are:

    The inbound event propagation method:

ChannelHandlerContext#fireChannelRegistered()

Report this document

For any questions or suggestions please email
cust-service@docsford.com