Chan Chen Coding...

Netty 4.0 源码分析(五):ChannelHandlerContext和ChannelHandler

ChannelHandlerContext接口

 1 package io.netty.channel;
 2 import io.netty.buffer.ByteBuf;
 3 import io.netty.buffer.MessageBuf;
 4 import io.netty.util.AttributeMap;
 5 import java.nio.channels.Channels;
 6 import java.util.Set;
 7 public interface ChannelHandlerContext
 8          extends AttributeMap, ChannelFutureFactory,
 9                  ChannelInboundInvoker, ChannelOutboundInvoker {
10     Channel channel();
11     ChannelPipeline pipeline();
12     EventExecutor executor();
13     String name();
14     ChannelHandler handler();
15     Set<ChannelHandlerType> types();
16     boolean hasInboundByteBuffer();
17     boolean hasInboundMessageBuffer();
18     ByteBuf inboundByteBuffer();
19     <T> MessageBuf<T> inboundMessageBuffer();
20     boolean hasOutboundByteBuffer();
21     boolean hasOutboundMessageBuffer();
22     ByteBuf outboundByteBuffer();
23     <T> MessageBuf<T> outboundMessageBuffer();
24     ByteBuf replaceInboundByteBuffer(ByteBuf newInboundByteBuf);
25     <T> MessageBuf<T> replaceInboundMessageBuffer(MessageBuf<T> newInboundMsgBuf);
26     ByteBuf replaceOutboundByteBuffer(ByteBuf newOutboundByteBuf);
27     <T> MessageBuf<T> replaceOutboundMessageBuffer(MessageBuf<T> newOutboundMsgBuf);
28     boolean hasNextInboundByteBuffer();
29     boolean hasNextInboundMessageBuffer();
30     ByteBuf nextInboundByteBuffer();
31     MessageBuf<Object> nextInboundMessageBuffer();
32     boolean hasNextOutboundByteBuffer();
33     boolean hasNextOutboundMessageBuffer();
34     ByteBuf nextOutboundByteBuffer();
35     MessageBuf<Object> nextOutboundMessageBuffer();
36     boolean isReadable();
37     void readable(boolean readable);
38 }

 

ChannelHandlerContext接口UML

 

ChannelHandlerContext接口的几个重要方法

ChannelPipeline pipeline();

返回属于当前ChannelHandlerContextChannelPipeline

 

EventExecutor executor();

EnventExcutor用于调度EventLoop中的event,这个方法返回当前的EventExecutor

 

一个Handler可以有多个Context

一个Handler可以被添加到多个ChannelPipeline。这就意味着一个ChannelHandler可以有多个ChannelHandlerContext

 

 

ChannelHandler接口

 1 package io.netty.channel;
 2  
 3 import io.netty.channel.group.ChannelGroup; 
 4 import java.lang.annotation.Documented;
 5 import java.lang.annotation.ElementType;
 6 import java.lang.annotation.Inherited;
 7 import java.lang.annotation.Retention;
 8 import java.lang.annotation.RetentionPolicy;
 9 import java.lang.annotation.Target;
10 import java.nio.channels.Channels;
11  
12 public interface ChannelHandler {
13     void beforeAdd(ChannelHandlerContext ctx) throws Exception;
14     void afterAdd(ChannelHandlerContext ctx) throws Exception;
15     void beforeRemove(ChannelHandlerContext ctx) throws Exception;
16     void afterRemove(ChannelHandlerContext ctx) throws Exception;
17     void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
18     void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
19     @Inherited
20     @Documented
21     @Target(ElementType.TYPE)
22     @Retention(RetentionPolicy.RUNTIME)
23     @interface Sharable {
24         // no value
25     }
26 }


 

ChannelHandlerUML

 

ChannelHandler中的几个重要方法

ChannelHandler有两个子接口,ChannelUpstreamHandlerChannelDownstreamHandler

1.    ChannelUpstreamHandler用于处理和拦截upstream中的ChannelEvent

2.    ChannelDownstreamHandler用于处理和拦截downstream中的ChannelEvent

 

状态信息

ChannelHandler一般需要存储一些状态信息,以下是【官方推荐】的方法,使用成员变量。

public class DataServerHandler extends SimpleChannelHandler {
     private boolean loggedIn;
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
         Channel ch = e.getChannel();
         Object o = e.getMessage();
         if (o instanceof LoginMessage) {
             authenticate((LoginMessage) o);
             loggedIn = true;
         } else (o instanceof GetDataMessage) {
             if (loggedIn) {
                 ch.write(fetchSecret((GetDataMessage) o));
             } else {
                 fail();
             }
         }
     }
     
 }
 
// Create a new handler instance per channel.
 
// See ClientBootstrap#setPipelineFactory(ChannelPipelineFactory).
 public class DataServerPipelineFactory implements ChannelPipelineFactory {
     public ChannelPipeline getPipeline() {
         return Channels.pipeline(new DataServerHandler());
     }
 }

 

 

或者使用ChannelLocal,代码如下

public final class DataServerState {      public static final ChannelLocal<Boolean> loggedIn = new ChannelLocal<>() {          protected Boolean initialValue(Channel channel) {              return false;          }      }      
}
 @Sharable  public class DataServerHandler extends SimpleChannelHandler {      @Override      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {          Channel ch = e.getChannel();          Object o = e.getMessage();          if (o instanceof LoginMessage) {              authenticate((LoginMessage) o);              DataServerState.loggedIn.set(ch, true);          } else (o instanceof GetDataMessage) {              if (DataServerState.loggedIn.get(ch)) {                  ctx.getChannel().write(fetchSecret((GetDataMessage) o));              } else {                  fail();              }          }      }      
}

 // Print the remote addresses of the authenticated clients:  ChannelGroup allClientChannels = ;  for (Channel ch: allClientChannels) {      if (DataServerState.loggedIn.get(ch)) {          System.out.println(ch.getRemoteAddress());      }  }


备注:因为笔者开始写Netty源码分析的时候,Netty 4.0还是处于Alpha阶段,之后的API可能还会有改动,笔者将会及时更改。使用开源已经有好几年的时间了,一直没有时间和精力来具体研究某个开源项目的具体实现,这次是第一次写开源项目的源码分析,如果文中有错误的地方,欢迎读者可以留言指出。对于转载的读者,请注明文章的出处。 希望和广大的开发者/开源爱好者进行交流,欢迎大家的留言和讨论。


-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;

posted on 2012-11-25 16:51 Chan Chen 阅读(12621) 评论(4)  编辑  收藏 所属分类: Netty

评论

# re: Netty 4.0 源码分析(五):ChannelHandlerContext和ChannelHandler[未登录] 2012-11-27 11:14 Alex

来点注释,怎么全是代码!  回复  更多评论   

# re: Netty 4.0 源码分析(五):ChannelHandlerContext和ChannelHandler 2012-11-27 11:47 Chan Chen

@Alex
具体的注释会在另外一篇文章(io.netty.handler)中提到,到时候会给出链接。这个文章只是对ChannelHandler和ChannelHandlerContext的初步印象理解,很浅显,很多解释也不到位。  回复  更多评论   

# re: Netty 4.0 源码分析(五):ChannelHandlerContext和ChannelHandler[未登录] 2013-01-22 15:13

字太小了 看不清  回复  更多评论   

# re: Netty 4.0 源码分析(五):ChannelHandlerContext和ChannelHandler 2013-11-18 21:19 字体

字太小了+1  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: