Netty学习-handler 的基类选择!

来源:互联网 发布:图片转换矢量图软件 编辑:程序博客网 时间:2024/06/05 03:32

netty 作为 rpc框架,其nio的特性很好,目前再看《Netty权威指南》书籍,下载了书中的例子照做,发现有些程序运行不了,通过解决分析,记录如下。

是netty 的入门例子,

我使用的版本是,

<dependency>    <groupId>io.netty</groupId>    <artifactId>netty-all</artifactId>    <version>4.1.9.Final</version></dependency>

作者写的书时候 版本肯定比这老,估计 ChannelHandlerAdapter是 包含了对io 事件的触发,但是我运行这个例子,始终运行不起来。

然后分析源码如下。


public abstract class ChannelHandlerAdapter implements ChannelHandler {    boolean added;    public ChannelHandlerAdapter() {    }    protected void ensureNotSharable() {        if(this.isSharable()) {            throw new IllegalStateException("ChannelHandler " + this.getClass().getName() + " is not allowed to be shared");        }    }    public boolean isSharable() {        Class clazz = this.getClass();        Map cache = InternalThreadLocalMap.get().handlerSharableCache();        Boolean sharable = (Boolean)cache.get(clazz);        if(sharable == null) {            sharable = Boolean.valueOf(clazz.isAnnotationPresent(Sharable.class));            cache.put(clazz, sharable);        }        return sharable.booleanValue();    }    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {    }    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {    }    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        ctx.fireExceptionCaught(cause);    }}


public interface ChannelHandler {    void handlerAdded(ChannelHandlerContext var1) throws Exception;    void handlerRemoved(ChannelHandlerContext var1) throws Exception;    /** @deprecated */    @Deprecated    void exceptionCaught(ChannelHandlerContext var1, Throwable var2) throws Exception;    @Inherited    @Documented    @Target({ElementType.TYPE})    @Retention(RetentionPolicy.RUNTIME)    public @interface Sharable {    }}




可以看到 ChannelHandlerAdapter,ChannelHandler 都没有包含对IO 事件的触发。所以我运行实例后,始终没有任何反应!感觉服务器和客户端没有发现通信!

既然找到了原因,那么解决也就简单了。


public class ChannelDuplexHandler extends ChannelInboundHandlerAdapter implements ChannelOutboundHandler {


public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {    public ChannelInboundHandlerAdapter() {    }    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelRegistered();    }    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelUnregistered();    }    public void channelActive(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelActive();    }    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelInactive();    }    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        ctx.fireChannelRead(msg);    }    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelReadComplete();    }    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {        ctx.fireUserEventTriggered(evt);    }    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {        ctx.fireChannelWritabilityChanged();    }    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        ctx.fireExceptionCaught(cause);    }}

这个ChannelDuplexHandler 可以即包含了对 io 事件(inbound) 又包含了对 用户事件(outbound)的触发。所以使用这个就可以完成运行!




0 0
原创粉丝点击