Netty整理(二)
現在我們來驗證一下channel的生命週期。
我們將EchoServerHandler修改如下,增加全部的監聽事件,並列印事件方法名稱。
/** * 事件處理器 */ @Slf4j public class EchoServerHandler extends ChannelInboundHandlerAdapter { /** * 監聽讀取事件 * @param ctx * @param msg * @throws Exception */ @Override public voidchannelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf data = (ByteBuf) msg; log.info(data.toString(CharsetUtil.UTF_8)); ctx.writeAndFlush(data); } /** * 監聽讀取完畢事件 * @param ctx * @throws Exception */ @Overridepublic 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。轉換成對應的字元檢視,就是‘\