1. 程式人生 > >Netty整理(二)

Netty整理(二)

Netty整理

現在我們來驗證一下channel的生命週期。

我們將EchoServerHandler修改如下,增加全部的監聽事件,並列印事件方法名稱。

/**
 * 事件處理器
 */
@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:
        好比廠裡的流水線一樣,可以在上面新增多個ChannelHanler,也可看成是一串 ChannelHandler 例項,攔截穿過 Channel 的輸入輸出 event,  ChannelPipeline 實現了攔截器的一種高階形式,使得使用者可以對事件的處理以及ChannelHanler之間互動獲得完全的控制權。

我們來看一下ChannelPipeline的原始碼

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()
            
           

相關推薦

Netty整理

接Netty整理 現在我們來驗證一下channel的生命週期。 我們將EchoServerHandler修改如下,增加全部的

Asp.Net Core WebAPI入門整理簡單示例

序列 open exc tor pda template ssa net found 一、Core WebAPI中的序列化 使用的是Newtonsoft.Json,自定義全局配置處理: // This method gets called by the runtime.

C# 異步編程Task整理異常捕捉

如果 console url 完全 list 標識 異步 通知 註意 一、在任務並行庫中,如果對任務運行Wait、WaitAny、WaitAll等方法,或者求Result屬性,都能捕獲到AggregateException異常。 可以將AggregateException異

MySQL整理

攔截器 delete blog 介紹 我們 mysq 直接 rem dep   一、MySQL操作表的約束     MySQL提供了一系列機制來檢查數據庫表中的數據是否滿足規定條件,以此來保證數據庫表中數據的準確性和一致性,這種機制就是約束。     (1)設置非空約束(N

機器學習算法整理邏輯回歸 python實現

alt bubuko 邏輯 style res n) regress com png 邏輯回歸(Logistic regression) 機器學習算法整理(二)邏輯回歸 python實現

Hive筆記整理

大數據 Hive [TOC] Hive筆記整理(二) Hive中表的分類 managed_table—受控表、管理表、內部表 表中的數據的生命周期/存在與否,受到了表結構的影響,當表結構被刪除的,表中的數據隨之一並被刪除。 默認創建的表就是這種表。 可以在cli中通過desc extended t

HBase筆記整理

大數據 HBase [TOC] HBase筆記整理(二) 邏輯結構 RowKey第一位 ColumnFamily ColumnQuiauer value(TimeStamps) Cell 物理結構 HMaster ----->NameNode 管理節點

Kafka筆記整理:Kafka Java API使用

大數據 Kafka Java [TOC] Kafka筆記整理(二):Kafka Java API使用 下面的測試代碼使用的都是下面的topic: $ kafka-topics.sh --describe hadoop --zookeeper uplooking01:2181,uplooking0

Redis筆記整理:Java API使用與Redis分布式集群環境搭建

數據庫 NoSQL Redis [TOC] Redis筆記整理(二):Java API使用與Redis分布式集群環境搭建 Redis Java API使用(一):單機版本Redis API使用 Redis的Java API通過Jedis來進行操作,因此首先需要Jedis的第三方庫,因為使用的是M

Eigen庫筆記整理

向量 pre geo 直接 gpo 歐拉角 () blog 初始化 Eigen/Geometry 模塊提供了各種旋轉和平移的表示 旋轉矩陣直接使用 Matrix3d 或 Matrix3f Eigen::Matrix3d rotation_matrix = Eigen::M

ElasticSearch筆記整理:CURL操作、ES插件、集群安裝與核心概念

大數據 ElasticSearch ELK [TOC] CURL操作 CURL簡介 curl是利用URL語法在命令行方式下工作的開源文件傳輸工具,使用curl可以簡單實現常見的get/post請求。簡單的認為是可以在命令行下面訪問url的一個工具。在centos的默認庫裏面是有curl工具的,如

Storm筆記整理:Storm本地開發案例—總和計算與單詞統計

大數據 實時計算 Storm [TOC] 概述 在Strom的API中提供了LocalCluster對象,這樣在不用搭建Storm環境或者Storm集群的情況下也能夠開發Storm的程序,非常方便。 基於Maven構建工程項目,其所需要的依賴如下: <dependency>

Scala筆記整理:Scala數據結構—數組、map與tuple

大數據 Scala [TOC] 數組 定長數組 如果你需要一個長度不變的數組,可以用Scala中的Array。例如: val numsArray = new Array[Int] (30) //長度為30的整數數組,所有元素初始化為0 val stringArrays = new Array [St

Spark筆記整理:RDD與spark核心概念名詞

大數據 Spark [TOC] Spark RDD 非常基本的說明,下面一張圖就能夠有基本的理解: Spark RDD基本說明 1、Spark的核心概念是RDD (resilient distributed dataset,彈性分布式數據集),指的是一個只讀的,可分區的分布式數據集,這個數據集的全

MySQL語句整理

包含 函數 通過 sum 運算符 database nts .... spa 數據庫操作前的準備 -- 創建數據庫 -- create database python_test_1 charset=utf8; -- 使用數據庫 -- use python_test

Python基礎班每日整理

每日 設置 語法 基礎 大件 例如 計算 str 功能 02_Python基礎_day02 Python中註釋的作用?單行和多行註釋在程序中對某些代碼進行標註說明,增強程序的可讀性。單行註釋:以#號開頭,再加一個空格,後面跟上註釋內容TODO註釋:# TODO 註釋內容

Python提高筆記整理

href 參數 類屬性 所有 建議 例如 類繼承 指定 super 1.多繼承以及MRO順序多繼承指的是子類繼承多個父類,可以通過三種方式訪問父類的方法:父類名.父類方法(self):這種方式容易造成父類方法被調用多次的問題,而且一旦父類名稱發生變化,子類調用的地方都需要修

Spark SQL筆記整理:DataFrame編程模型與操作案例

代碼 最重要的 ssi func nbu 產生 michael array image DataFrame原理與解析 Spark SQL和DataFrame 1、Spark SQL是Spark中的一個模塊,主要用於進行結構化數據的處理。它提供的最核心的編程抽象,就是Data

nodejs學習整理

模組 模組分類:自定義模組-自己寫的,核心模組-官方的,第三方模組-組織或個人公開的 nodejs會為每一個檔案新增如下程式碼: (function(exports,require,module,__dirname,__filename) { //程式碼 }) module:當前模組

【C語言實現串列埠通訊知識點整理】遇到的問題整理待續....

1.c編譯錯誤--error:stray \357 in program UTF-8編碼問題。UTF-8編碼有BOM和無BOM格式。BOM,ByteOrderMark(位元組標記順序),表明使用UTF8來進行編碼。UTF-8的BOM通常為3個位元組EF BB BF。轉換成對應的字元檢視,就是‘\