Netty組件介紹

在學(xué)習(xí)Netty之前镀赌,建議首先學(xué)習(xí)一個(gè)NIO宏怔,對(duì)關(guān)鍵的NIO組件有一個(gè)清醒認(rèn)識(shí)

Buffer

Selector

總覽

  • Bootstrap or ServerBootstrap
  • EventLoop
  • EventLoopGroup
  • ChannelPipeline
  • Future or ChannelFuture
  • ChannelInitializer
  • ChannelHandler
  • ByteToMessageDecoder
  • MessageToByteEncoder

ServerBootstrap

一個(gè)Netty應(yīng)用通常由一個(gè)Bootstrap開始踪少,它主要作用是配置整個(gè)Netty程序,串聯(lián)起各個(gè)組件刻剥。

EventLoop

一個(gè)EventLoop可以為多個(gè)Channel服務(wù)驰后。 EventLoopGroup會(huì)包含多個(gè)EventLoop

ChannelPipeline,ChannelHandler

從PipeLine這個(gè)單詞中可以看出來,是一個(gè)管道懊烤,處理連接梯醒。我們的業(yè)務(wù)代碼handler一般都是放在這個(gè)管道中的

那么疑問來了,這個(gè)管道中的處理順序是什么樣呢奸晴?

 ChannelPipeline cp = channel.pipeline(); 
 cp.addLast("encoder", new HttpResponseEncoder());//1.負(fù)責(zé)輸出
 cp.addLast("decoder", new HttpRequestDecoder());//2.負(fù)責(zé)把客戶端的數(shù)據(jù)解碼
 cp.addLast("handler", new HttpDispatchServerHandler());//3.自定義的業(yè)務(wù)處理器

按照我們執(zhí)行順序肯定不是根據(jù)添加順序來處理的冤馏,應(yīng)該是:2,把客戶端的數(shù)據(jù)解碼->3.對(duì)解碼數(shù)據(jù)處理->1.加密返回給客戶端。

那么 Netty 是怎么處理的呢寄啼?

ChannelHandler有兩個(gè)子類ChannelInboundHandler和ChannelOutboundHandler逮光,這兩個(gè)類對(duì)應(yīng)了兩個(gè)數(shù)據(jù)流向代箭,如果數(shù)據(jù)是從外部流入我們的應(yīng)用程序,我們就看做是inbound涕刚,相反便是outbound

ChannelInitializer

顧名思義,這個(gè)就是channel初始化的容器嗡综,在這個(gè)里面設(shè)置處理器

 ServerBootstrap bootstrap = new ServerBootstrap();
        bossGroup = new NioEventLoopGroup();//負(fù)責(zé)綁定channel到selector
        workerGroup = new NioEventLoopGroup();//負(fù)責(zé)從selector中讀取事件
        bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .localAddress(6969).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
                .childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel channel) throws Exception {
                ChannelPipeline cp = channel.pipeline();
                cp.addLast("idleStateHandler", new IdleStateHandler(5, 5, 5, TimeUnit.SECONDS));
                cp.addLast("decoder", new HttpRequestDecoder());
                cp.addLast("encoder", new HttpResponseEncoder());
                cp.addLast("aggregator", new HttpObjectAggregator(1048576));
                cp.addLast("deflater", new HttpContentCompressor());
                cp.addLast("handler", new HttpDispatchServerHandler());
                cp.addLast("out", new AcceptorIdleStateTrigger());
            }
        }).option(ChannelOption.SO_BACKLOG, 128);
        try {
            channel = bootstrap.bind().awaitUninterruptibly().channel();
            showBanner(6969);
        } catch (Exception ie) {
            throw new RuntimeException(ie);
        }

ChannelFuture

Netty中的連接都可以是異步的,但是也可以設(shè)置為非異步

ChannelFuture

Channel 每個(gè)操作都會(huì)返回一個(gè) ChannelFutrue 因?yàn)槭钱惒降亩拍晕覀優(yōu)槊總€(gè)異步的結(jié)果极景,添加一個(gè)監(jiān)聽,比如:

# 當(dāng)完成關(guān)閉動(dòng)作,就執(zhí)行監(jiān)聽器內(nèi)容
f = f.channel().closeFuture().await();  
f.addListener(new ChannelFutureListener() {  
    @Override  
    public void operationComplete(ChannelFuture future) throws Exception {  
        System.out.println("success complete!!ok!!");  
    }  
});  

當(dāng)然還有一種方法驾茴, 就是await()盼樟,此返回會(huì)等待上一個(gè)操作完成,在進(jìn)行下一個(gè)操作锈至。但是推薦使用第一種晨缴。

ByteToMessageDecoder

解密器,可以自定義協(xié)議峡捡,通過集成改接口击碗,重寫 decode 方法把二進(jìn)制,轉(zhuǎn)換為我們系統(tǒng)可以處理的對(duì)象

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * 把字節(jié)轉(zhuǎn)換為int
 * 繼承抽象類ByteToMessageDecoder實(shí)現(xiàn)解碼器
 */
public class ByteToIntegerDecoder extends ByteToMessageDecoder {

    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in,
                       List<Object> out) throws Exception {
        if (in.readableBytes() >= 4) {  // Check if there are at least 4 bytes readable
            int n = in.readInt();
            System.err.println("ByteToIntegerDecoder decode msg is " + n);
            out.add(n);      //Read integer from inbound ByteBuf, add to the List of decodec messages
        }
    }
}

編碼器

將我們系統(tǒng)處理完的信息们拙,編碼成稍途,二進(jìn)制,傳出砚婆,給調(diào)用者

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class IntegerToByteEncoder extends MessageToByteEncoder<Integer> {
    @Override
    public void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out)
            throws Exception {
        System.err.println("IntegerToByteEncoder encode msg is " + msg);
        out.writeInt(msg);
    }
}

解碼后的數(shù)據(jù)怎么使用

對(duì)于加密后的數(shù)據(jù)械拍,可以直接強(qiáng)制轉(zhuǎn)換為我們解碼的對(duì)象

public class BusinessHandler extends ChannelInboundHandlerAdapter {
    private Logger  logger  = LoggerFactory.getLogger(BusinessHandler.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    //因?yàn)槲覀兊慕獯a其中指定是Int類型,所以我們就可以装盯,強(qiáng)制轉(zhuǎn)換為Int殊者,這里為了好理解,假如我們的解碼器验夯,中是轉(zhuǎn)換了Person,那么在我們的處理器中就摔刁,可以強(qiáng)制換換為Person
        Person person = (Person) msg;
        logger.info("BusinessHandler read msg from client :" + person);
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挥转,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子共屈,更是在濱河造成了極大的恐慌绑谣,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拗引,死亡現(xiàn)場(chǎng)離奇詭異借宵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)矾削,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門壤玫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豁护,“玉大人,你說我怎么就攤上這事欲间〕铮” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵猎贴,是天一觀的道長(zhǎng)班缎。 經(jīng)常有香客問我,道長(zhǎng)她渴,這世上最難降的妖魔是什么达址? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮趁耗,結(jié)果婚禮上沉唠,老公的妹妹穿的比我還像新娘。我一直安慰自己对粪,他們只是感情好右冻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著著拭,像睡著了一般纱扭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上儡遮,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天乳蛾,我揣著相機(jī)與錄音,去河邊找鬼鄙币。 笑死肃叶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的十嘿。 我是一名探鬼主播因惭,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绩衷!你這毒婦竟也來了蹦魔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤咳燕,失蹤者是張志新(化名)和其女友劉穎勿决,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體招盲,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡低缩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曹货。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咆繁。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讳推,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出么介,到底是詐尸還是另有隱情娜遵,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布壤短,位于F島的核電站设拟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏久脯。R本人自食惡果不足惜纳胧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帘撰。 院中可真熱鬧跑慕,春花似錦、人聲如沸摧找。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蹬耘。三九已至芝雪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間综苔,已是汗流浹背惩系。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留如筛,地道東北人堡牡。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像杨刨,于是被迫代替她去往敵國(guó)和親晤柄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容