一.学习Netty之ChannelHandler接口

他的作用是处理一些io事件,或者阻止一些io操作,并且跳转到ChannelPipeline的下一个handler去

通常情况下,我们不会选择是实现这个接口,而是继承ChannelHandlerAdapter

ChannelHandler 通常会提供一个 ChannelHandlerContext. 所以你会看到ChannelHandler的每一个方法都有一个参数ChannelHandlerContext

ChannelHandler可以处理读写事件, 动态的修改pipeline, 存储一些数据到handler上(用AttributesKey)

状态管理

一个ChannelHandler通常需要存储一些状态信息,最简单的方式就是保存到成员变量里,如是否登录过了?

在这里,是否登录过了这个状态信息是每一个connection都需要的,所以,我们要为每一个channel创建一个handler的实例,

// Create a new handler instance per channel.
   // See ChannelInitializer.initChannel(Channel).
   public class DataServerInitializer extends ChannelInitializer<Channel> {
        @Override
       public void initChannel(Channel channel) {
           channel.pipeline().addLast("handler", new DataServerHandler());
       }
   }

使用 AttributeKeys

你可以用他取代成员变量来保存一些信息,他是附属于ChannelHandlerContext

 public interface Message {
       // your methods here
   }
  
    @Sharable
   public class DataServerHandler extends SimpleChannelInboundHandler<Message> {
       private final AttributeKey<Boolean> auth =
             AttributeKey.valueOf("auth");
  
        @Override
       protected void messageReceived(ChannelHandlerContext ctx, Message message) {
           Attribute<Boolean> attr = ctx.attr(auth);
           Channel ch = ctx.channel();
  
           if (message instanceof LoginMessage) {
               authenticate((LoginMessage) o);
               attr.set(true);
           } else (message instanceof GetDataMessage) {
               if (Boolean.TRUE.equals(attr.get())) {
                   ch.write(fetchSecret((GetDataMessage) o));
               } else {
                   fail();
               }
           }
       }
       ...
   }

下面这个比较有意思

Now that the state of the handler is attached to the ChannelHandlerContext, you can add the same handler instance to different pipelines:
   public class DataServerInitializer extends ChannelInitializer<Channel> {
  
       private static final DataServerHandler SHARED = new DataServerHandler();
  
        @Override
       public void initChannel(Channel channel) {
           channel.pipeline().addLast("handler", SHARED);
       }
   }

这里和上一节状态管理的代码有些区别,都是DataServerHandler 为什么哪里的需要每次都new一个,而这里直接是一个静态的成员变量,也就是说可以共享的.

他们的区别仅仅是,前一节的DataServerHandler 使用了一个private boolean loggedIn; 来保存登录状态,而这里使用了一个AttributeKey.因为前一个DataServerHandler的状态是不能共享的,每个都应该有一个,如果共用一个,岂不是有一个人登录了,所有人都登录了?而AttributeKey是跟上下文绑定在一起,上下文每一个连接都有一个,所以不冲突

另外,我们注意到,@Sharable 这个注解被加在了本节的DataServerHandler 上,这表明他是可以共享的

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Exception caught when during method invocation. request:net.risesoft.rpc.itemAdmin.DocumentManager.edit4Position(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) requestId=1771270236171928205 java.lang.reflect.InvocationTargetException: null at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.weibo.api.motan.rpc.DefaultProvider.invoke(DefaultProvider.java:64) at com.weibo.api.motan.rpc.AbstractProvider.call(AbstractProvider.java:52) at com.weibo.api.motan.transport.ProviderMessageRouter.call(ProviderMessageRouter.java:98) at com.weibo.api.motan.transport.ProviderProtectedMessageRouter.call(ProviderProtectedMessageRouter.java:75) at com.weibo.api.motan.transport.ProviderMessageRouter.handle(ProviderMessageRouter.java:93) at com.weibo.api.motan.transport.support.DefaultRpcHeartbeatFactory$HeartMessageHandleWrapper.handle(DefaultRpcHeartbeatFactory.java:98) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.processRequest(NettyChannelHandler.java:155) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.processMessage(NettyChannelHandler.java:133) at com.weibo.api.motan.transport.netty4.NettyChannelHandler.access$000(NettyChannelHandler.java:32) at com.weibo.api.motan.transport.netty4.NettyChannelHandler$1.run(NettyChannelHandler.java:73) at java.util.concurrent.ThreadPoolExecutor.runWorker(Threa是哪里的问题
07-14

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值