前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty整理(二) 顶

Netty整理(二) 顶

作者头像
算法之名
发布2019-09-29 17:30:58
3550
发布2019-09-29 17:30:58
举报
文章被收录于专栏:算法之名算法之名

Netty整理

现在我们来验证一下channel的生命周期。

我们将EchoServerHandler修改如下,增加全部的监听事件,并打印事件方法名称。

代码语言:javascript
复制
/**
 * 事件处理器
 */
@Slf4j
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    /**
     * 监听读取事件
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf data = (ByteBuf) msg;
        log.info(data.toString(CharsetUtil.UTF_8));
        ctx.writeAndFlush(data);
    }

    /**
     * 监听读取完毕事件
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("channelReadComplete");
    }

    /**
     * 监听异常事件
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 将channel注册到EventLoop的Selector多路复用器中
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channelRegistered");
    }

    /**
     * channel未注册到EventLoop中
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("channelUnregistered");
    }

    /**
     * 有连接,变为活跃状态
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelActive");
    }

    /**
     * 没有连接,非活跃状态
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelInactive");
    }
}

启动EchoServer,打开telnet连接到端口,我们可以看到

admindeMacBook-Pro:~ admin$ telnet 127.0.0.1 10101

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

sdfs

sdfs

^]

telnet> quit

Connection closed.

整个过程为连接,发送字符串sdfs,退出连接

服务端日志为

2019-10-01 05:33:36.960 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelRegistered

2019-10-01 05:33:36.960 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelActive

2019-10-01 05:33:54.439 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : sdfs

2019-10-01 05:33:54.442 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelReadComplete

2019-10-01 05:34:22.527 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelReadComplete

2019-10-01 05:34:22.529 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelInactive

2019-10-01 05:34:22.529 INFO 543 --- ntLoopGroup-3-1 c.g.websocket.netty.EchoServerHandler : channelUnregistered

整个生命周期正如前面写到一样

Channel的生命周期为:(1)channelRegistered->(3)channelActive->(4)channelInactive->(2)channelUnregistered

ChannelPipeline:

代码语言:txt
复制
     好比厂里的流水线一样,可以在上面添加多个ChannelHanler,也可看成是一串 ChannelHandler 实例,拦截穿过 Channel 的输入输出 event,  ChannelPipeline 实现了拦截器的一种高级形式,使得用户可以对事件的处理以及ChannelHanler之间交互获得完全的控制权。

我们来看一下ChannelPipeline的源码

代码语言:javascript
复制
public interface ChannelPipeline
        extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {

    /**
     * 在管道的首位置添加一个channelhandler
     */
    ChannelPipeline addFirst(String name, ChannelHandler handler);

    /**
     * 同上,多了一个线程池参数
     */
    ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);

    /**
     * 在管道的最末端添加一个channelhandler
     */
    ChannelPipeline addLast(String name, ChannelHandler handler);

    /**
     * 同上,多了一个线程池参数
     */
    ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);

    /**
     * 在一个管道中已存在的channelhandler之前插入另外一个channelhandler
     */
    ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);

    /**
     * 同上,多了一个线程池参数
     */
    ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);

    /**
     * 在管道已有多一个channelhandler之后插入另外一个channelhandler
     */
    ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);

    /**
     * 同上,多了一个线程池参数
     */
    ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);

    /**
     * 在该管道的首位置放入一组channelhandler
     *
     */
    ChannelPipeline addFirst(ChannelHandler... handlers);

    /**
     * 同上,多了一个线程池参数
     *
     */
    ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);

    /**
     * 在管道的最末端放入一组channelhandler
     *
     */
    ChannelPipeline addLast(ChannelHandler... handlers);

    /**
     * 同上,多了一个线程池参数
     *
     */
    ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);

    /**
     * 从管道中移除一个channelhandler
     */
    ChannelPipeline remove(ChannelHandler handler);

    /**
     * 根据名字在管道中移除一个channelhandler
     */
    ChannelHandler remove(String name);

    /**
     * 根据类名在管道中移除一个channelhandler
     */
    <T extends ChannelHandler> T remove(Class<T> handlerType);

    /**
     * 移除管道中首个channelhandler
     */
    ChannelHandler removeFirst();

    /**
     * 移除管道中末个channelhandler
     */
    ChannelHandler removeLast();

    /**
     * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字
     */
    ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);

    /**
     * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字
     */
    ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);

    /**
     * 在管道中用新的channelhandler替换旧的channelhandler,中间参数都是替换者的名字
     */
    <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
                                         ChannelHandler newHandler);

    /**
     * 返回管道中首个channelhandler
     */
    ChannelHandler first();

    /**
     * 获取第一个管道处理器上下文
     */
    ChannelHandlerContext firstContext();

    /**
     * 获取管道中最后一个channelhandler
     */
    ChannelHandler last();

    /**
     * 获取管道中最后一个管道处理器上下文
     */
    ChannelHandlerContext lastContext();

    /**
     * 根据名字获取管道中的一个channelhandler
     */
    ChannelHandler get(String name);

    /**
     * 根据类获取一个channelhandler
     */
    <T extends ChannelHandler> T get(Class<T> handlerType);

    /**
     * 根据channelhandler获取一个管道处理器上下文
     */
    ChannelHandlerContext context(ChannelHandler handler);

    /**
     * 根据名字获取一个管道处理器上下文
     */
    ChannelHandlerContext context(String name);

    /**
     * 根据一个channelhandler的类名获取一个管道处理器上下文
     */
    ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);

    /**
     * 返回一个管道
     */
    Channel channel();

    /**
     * 返回管道中的channelhandler的名称列表
     */
    List<String> names();

    /**
     * Converts this pipeline into an ordered {@link Map} whose keys are
     * handler names and whose values are handlers.
     */
    Map<String, ChannelHandler> toMap();

    @Override
    ChannelPipeline fireChannelRegistered();

     @Override
    ChannelPipeline fireChannelUnregistered();

    @Override
    ChannelPipeline fireChannelActive();

    @Override
    ChannelPipeline fireChannelInactive();

    @Override
    ChannelPipeline fireExceptionCaught(Throwable cause);

    @Override
    ChannelPipeline fireUserEventTriggered(Object event);

    @Override
    ChannelPipeline fireChannelRead(Object msg);

    @Override
    ChannelPipeline fireChannelReadComplete();

    @Override
    ChannelPipeline fireChannelWritabilityChanged();

    @Override
    ChannelPipeline flush();
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档