java中ChannelHandler的用法详解

  

<强> java中ChannelHandler的用法详解

  

<强>前言:
  

  

ChannelHandler处理一个I/O事件或者拦截一个I/O操作,在它的ChannelPipeline中将其递交给相邻的下一个处理程序。

  

<强>通过继承ChannelHandlerAdapter来代替
  

  

因为这个接口有许多的方法需要实现,你或许希望通过继承ChannelHandlerAdapter来代替。

  

<强>上下文对象
  

  

一个ChannelHandler和一个ChannelHandlerContext对象一起被提供。一个ChannelHander通过一个上下文对象和其所属的那个ChannelPipeline进行交互。使用上下文对象,ChannelHandler可以向上或者向下传递事件、动态地修改管道,或者存储与处理程序相关的信息(使用AttributeKeys)。

  

<>强状态管理
  

  

一个ChannelHandler经常需要存储一些状态相关的信息。最简单和推荐的方法是使用成员变量:

        公共接口消息{//你的方法   }      公开课DataServerHandler延伸SimpleChannelInboundHandler{      私人布尔loggedIn;      @Override   保护无效messageReceived (ChannelHandlerContext ctx、消息消息){   通道ch=e.getChannel ();   如果(消息instanceof LoginMessage) {   ((LoginMessage)消息进行身份验证);   loggedIn=true;   其他}(消息instanceof GetDataMessage) {   如果(loggedIn) {   ch.write (fetchSecret ((GetDataMessage)消息));   其他}{   失败();   }   }   }   …   }      之前      

因为处理程序实例有一个状态变量专注于一个连接,你必须为每一个处理程序实例创建一个新的处理程序实例,来避免竞态的情况以至于未认证的客户端可以获得机密的信息:

     //创建一个新的处理程序实例每通道。//看到ChannelInitializer.initChannel(通道)。   公开课DataServerInitializer延伸ChannelInitializer{   @Override   公共空间initChannel(频道频道){   channel.pipeline ()。addLast(“处理器”,新的DataServerHandler ());   }   }   之前      

<强>使用AttributeKeys
  

  

虽然使用成员变量来保存一个处理程序的状态是被推荐的,然而,由于一些原因你或许不想创建很多的处理器实例。在这种情况下,你可以使用附在ChannelHandlerContext上的AttributeKeys:

        公共接口消息{//你的方法   }   @Sharable   公开课DataServerHandler延伸SimpleChannelInboundHandler{   私人最终AttributeKeyauth=AttributeKey.valueOf(“身份验证”);   @Override   保护无效messageReceived (ChannelHandlerContext ctx、消息消息){   Attributeattr=ctx.attr(身份验证);   通道ch=ctx.channel ();   如果(消息instanceof LoginMessage) {   验证((LoginMessage) o);   attr.set(真正的);   其他}(消息instanceof GetDataMessage) {   如果(Boolean.TRUE.equals (attr.get ())) {   ch.write (fetchSecret ((GetDataMessage) o));   其他}{   失败();   }   }   }   …   }   之前      

现在处理程序的状态被附在了ChannelHandlerContext上了,你可以添加同样的处理程序实例到不同的管道上:

        公开课DataServerInitializer延伸ChannelInitializer{      私有静态最终DataServerHandler共享=new DataServerHandler ();      @Override   公共空间initChannel(频道频道){   channel.pipeline ()。addLast(“处理器”,共享);   }   }      之前      

<强> @Sharable注解
  

  

在上面使用AttributeKey的例子中,你应该已经注意到了@Sharable注解。

  

如果一个ChannelHandler被注解为@Sharable,那意味着你可以只创建一个处理程序实例,并把它添加到一个或多个ChannelPipeline中多次,并不用考虑竞态的情况。

  

如果这个注解没有指定,你就只能为每次需要添加到管道中的处理程序,每次创建一个新的实例。因为它有非共享的状态,比如:成员变量。

  

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

java中ChannelHandler的用法详解