二. 学习Netty之ChannelHandlerContext

ChannelHandlerContext可以确保一个ChannelHandler和它的pipeline和其他的handler联系起来

  1. handler可以通知pipeline里的下一个handler
  2. handler可以动态的修改它的pipeline在运行时

通知: ChannelHandler可以通知同一个ChannelPipeline 中的下一个Handler 修改 pipeline() 通过这个方法,handler可以修改同一个ChannelPipeline最近的一个 handler

保存上下文,以后需要的时候再用

public class MyHandler extends ChannelHandlerAdapter {
  
       private ChannelHandlerContext ctx;
  
       public void beforeAdd(ChannelHandlerContext ctx) {
           this.ctx = ctx;
       }
  
       public void login(String username, password) {
           ctx.write(new LoginMessage(username, password));
       }
       ...
   }

3.存储状态类的信息 attr(AttributeKey)

4.一个handler可以有不止一个的context 一个handler可以被添加到多个pipeline,也可以被一个pipeline添加多次

public class FactorialHandler extends ChannelHandlerAdapter {
  
     private final AttributeKey<Integer> counter = AttributeKey.valueOf("counter");
  
     // This handler will receive a sequence of increasing integers starting
     // from 1.
      @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) {
       Attribute<Integer> attr = ctx.getAttr(counter);
       Integer a = ctx.getAttr(counter).get();
  
       if (a == null) {
         a = 1;
       }
  
       attr.set(a * (Integer) msg);
     }
   }
  
   // Different context objects are given to "f1", "f2", "f3", and "f4" even if
   // they refer to the same handler instance.  Because the FactorialHandler
   // stores its state in a context object (using an AttributeKey), the factorial is
   // calculated correctly 4 times once the two pipelines (p1 and p2) are active.
   FactorialHandler fh = new FactorialHandler();
  
   ChannelPipeline p1 = Channels.pipeline();
   p1.addLast("f1", fh);
   p1.addLast("f2", fh);
  
   ChannelPipeline p2 = Channels.pipeline();
   p2.addLast("f3", fh);
   p2.addLast("f4", fh);
   

注意: 每个channel都有一个pipeline 每个handler都有一个context

[attr相当于就是session.一开始我有疑惑,每个handler都有一个context, 那么context.attr() 相当于每个handler的attr都不一样了,怎么会像是session的功能呢? 原来,attr是附着在channel上的,而不是context上.context.attr实际上调用的还是channel.attr] ** 上面的理解是错误的,不应该吧attr类比为session. 通常,我们怎么标识客户端呢?一个ip+port ,放在全局的map里作为key.那么这个map才相当于session 而attr要理解为附件,这个附近可以是哪些东西呢,比如一个auth串, 权限验证的东西, 加密的东西等等.**

一个bossGroup是一个线程组,在bind的时候创建ServerChannel,也就意味着即使这是一个线程组, 那么只绑定一个端口的时候,那么也只有一条线程accept用户的接入请求。

handler() childHandler()

handler() 里的handler是在bossGroup里执行的,也就是说当只绑定一个端口的时候,这个handler是和accept在一个线程中的。而childHandler里的handler则是在workerGroup里执行的

转载于:https://my.oschina.net/u/1777377/blog/524230

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值