保健励志美文体育育儿作文
投稿投诉
作文动态
热点娱乐
育儿情感
教程科技
体育养生
教案探索
美文旅游
财经日志
励志范文
论文时尚
保健游戏
护肤业界

netty系列之channelHandlerContext详

  简介
  我们知道ChannelHandler有两个非常重要的子接口,分别是ChannelOutboundHandler和ChannelInboundHandler,基本上这两个handler接口定义了所有channelinbound和outbound的处理逻辑。
  不管是ChannelHandler还是ChannelOutboundHandler和ChannelInboundHandler,几乎他们中所有的方法都带有一个ChannelHandlerContext参数,那么这个ChannelHandlerContext到底是做什么用的呢?它和handler、channel有什么关系呢?ChannelHandlerContext和它的应用
  熟悉netty的朋友应该都接触过ChannelHandlerContext,如果没有的话,这里有一个简单的handler的例子:publicclassChatServerHandlerextendsSimpleChannelInboundHandlerString{OverridepublicvoidchannelActive(ChannelHandlerContextctx)throwsException{log。info(acceptedchannel:{},ctx。channel());log。info(acceptedchannelparent:{},ctx。channel()。parent());channel活跃ctx。write(ChannelActive状态!r);ctx。flush();}}
  这里的handler继承了SimpleChannelInboundHandler,只需要实现对应的方法即可。这里实现的是channelActive方法,在channelActive方法中,传入了一个ChannelHandlerContext参数,我们可以通过使用ChannelHandlerContext来调用它的一些方法。
  先来看一下ChannelHandlerContext的定义:publicinterfaceChannelHandlerContextextendsAttributeMap,ChannelInboundInvoker,ChannelOutboundInvoker{
  首先ChannelHandlerContext是一个AttributeMap,可以用来存储多个数据。
  然后ChannelHandlerContext继承了ChannelInboundInvoker和ChannelOutboundInvoker,可以触发inbound和outbound的一些方法。
  除了继承来的一些方法之外,ChannelHandlerContext还可以作为channel,handler和pipline的沟通桥梁,因为可以从ChannelHandlerContext中获取到对应的channel,handler和pipline:Channelchannel();ChannelHandlerhandler();ChannelPipelinepipeline();
  还要注意的是ChannelHandlerContext还返回一个EventExecutor,用来执行特定的任务:EventExecutorexecutor();
  接下来,我们具体看一下ChannelHandlerContext的实现。AbstractChannelHandlerContext
  AbstractChannelHandlerContext是ChannelHandlerContext的一个非常重要的实现,虽然AbstractChannelHandlerContext是一个抽象类,但是它基本上实现了ChannelHandlerContext的所有功能。
  首先看一下AbstractChannelHandlerContext的定义:abstractclassAbstractChannelHandlerContextimplementsChannelHandlerContext,ResourceLeakHint
  AbstractChannelHandlerContext是ChannelHandlerContext的一个具体实现。
  通常来说一个handler对应一个ChannelHandlerContext,但是在一个程序中可能会有多于一个handler,那么如何在一个handler中获取其他的handler呢?
  在AbstractChannelHandlerContext中有两个同样是AbstractChannelHandlerContext类型的next和prev,从而使得多个AbstractChannelHandlerContext可以构建一个双向链表。从而可以在一个ChannelHandlerContext中,获取其他的ChannelHandlerContext,从而获得handler处理链。volatileAbstractChannelHandlerContextnext;volatileAbstractChannelHandlerContextprev;
  AbstractChannelHandlerContext中的pipeline和executor都是通过构造函数传入的:AbstractChannelHandlerContext(DefaultChannelPipelinepipeline,EventExecutorexecutor,Stringname,Classlt;?extendsChannelHandlerhandlerClass){this。nameObjectUtil。checkNotNull(name,name);this。pipelinepipeline;this。executorexecutor;this。executionMaskmask(handlerClass);ItsorderedifitsdrivenbytheEventLooporthegivenExecutorisaninstanceofOrderedEventExecutor。orderedexecutornullexecutorinstanceofOrderedEventExecutor;}
  可能有朋友会有疑问了,ChannelHandlerContext中的channel和handler是如何得到的呢?
  对于channel来说,是通过pipeline来获取的:publicChannelchannel(){returnpipeline。channel();}
  对于handler来说,在AbstractChannelHandlerContext中并没有对其进行实现,需要在继承AbstractChannelHandlerContext的类中进行实现。
  对于EventExecutor来说,可以通过构造函数向AbstractChannelHandlerContext传入一个新的EventExecutor,如果没有传入或者传入为空的话,则会使用channel中自带的EventLoop:publicEventExecutorexecutor(){if(executornull){returnchannel()。eventLoop();}else{returnexecutor;}}
  因为EventLoop继承自OrderedEventExecutor,所以它也是一个EventExecutor。
  EventExecutor主要用来异步提交任务来执行,事实上ChannelHandlerContext中几乎所有来自于ChannelInboundInvoker和ChannelOutboundInvoker的方法都是通过EventExecutor来执行的。
  对于ChannelInboundInvoker来说,我们以方法fireChannelRegistered为例:publicChannelHandlerContextfireChannelRegistered(){invokeChannelRegistered(findContextInbound(MASKCHANNELREGISTERED));returnthis;}staticvoidinvokeChannelRegistered(finalAbstractChannelHandlerContextnext){EventExecutorexecutornext。executor();if(executor。inEventLoop()){next。invokeChannelRegistered();}else{executor。execute(newRunnable(){Overridepublicvoidrun(){next。invokeChannelRegistered();}});}}
  fireChannelRegistered调用了invokeChannelRegistered方法,invokeChannelRegistered则调用EventExecutor的execute方法,将真实的调用逻辑封装在一个runnable类中执行。
  注意,在调用executor。execute方法之前有一个executor是否在eventLoop中的判断。如果executor已经在eventLoop中了,那么直接执行任务即可,不需要启用新的线程。
  对于ChannelOutboundInvoker来说,我们以bind方法为例,看一下EventExecutor是怎么使用的:publicChannelFuturebind(finalSocketAddresslocalAddress,finalChannelPromisepromise){ObjectUtil。checkNotNull(localAddress,localAddress);if(isNotValidPromise(promise,false)){cancelledreturnpromise;}finalAbstractChannelHandlerContextnextfindContextOutbound(MASKBIND);EventExecutorexecutornext。executor();if(executor。inEventLoop()){next。invokeBind(localAddress,promise);}else{safeExecute(executor,newRunnable(){Overridepublicvoidrun(){next。invokeBind(localAddress,promise);}},promise,null,false);}returnpromise;}
  可以看到执行的逻辑和invokeChannelRegistered方法很类似,也是先判断executor在不在eventLoop中,如果在的话直接执行,如果不在则放在executor中执行。
  上面的两个例子中都调用了next的相应方法,分别是next。invokeChannelRegistered和next。invokeBind。
  我们知道ChannelHandlerContext只是一个封装,它本身并没有太多的业务逻辑,所以next调用的相应方法,实际上是Context中封装的ChannelInboundHandler和ChannelOutboundHandler中的业务逻辑,如下所示:privatevoidinvokeUserEventTriggered(Objectevent){if(invokeHandler()){try{((ChannelInboundHandler)handler())。userEventTriggered(this,event);}catch(Throwablet){invokeExceptionCaught(t);}}else{fireUserEventTriggered(event);}}privatevoidinvokeBind(SocketAddresslocalAddress,ChannelPromisepromise){if(invokeHandler()){try{((ChannelOutboundHandler)handler())。bind(this,localAddress,promise);}catch(Throwablet){notifyOutboundHandlerException(t,promise);}}else{bind(localAddress,promise);}}
  所以,从AbstractChannelHandlerContext可以得知,ChannelHandlerContext接口中定义的方法都是调用的handler中具体的实现,Context只是对handler的封装。DefaultChannelHandlerContext
  DefaultChannelHandlerContext是AbstractChannelHandlerContext的一个具体实现。
  我们在讲解AbstractChannelHandlerContext的时候提到过,AbstractChannelHandlerContext中并没有定义具体的handler的实现,而这个实现是在DefaultChannelHandlerContext中进行的。
  DefaultChannelHandlerContext很简单,我们看一下它的具体实现:finalclassDefaultChannelHandlerContextextendsAbstractChannelHandlerContext{privatefinalChannelHandlerhandler;DefaultChannelHandlerContext(DefaultChannelPipelinepipeline,EventExecutorexecutor,Stringname,ChannelHandlerhandler){super(pipeline,executor,name,handler。getClass());this。handlerhandler;}OverridepublicChannelHandlerhandler(){returnhandler;}}
  DefaultChannelHandlerContext中额外提供了一个ChannelHandler属性,用来存储传入的ChannelHandler。
  到此DefaultChannelHandlerContext可以传入ChannelHandlerContext中一切必须的handler,channel,pipeline和EventExecutor。总结
  本节我们介绍了ChannelHandlerContext和它的几个基本实现,了解到了ChannelHandlerContext是对handler,channel和pipline的封装,ChannelHandlerContext中的业务逻辑,实际上是调用的是底层的handler的对应方法。这也是我们在自定义handler中需要实现的方法。本文已收录于http:www。flydean。com044nettychannelhandlercontext
  最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
  欢迎关注我的公众号:程序那些事,懂技术,更懂你!

有关毕业的伤感句子大全六月,总是阳光灿烂。六月,总要曲终人散。六月,我们拒绝伤感。小编收集了有关毕业的伤感句子大全,欢迎阅读。1、一杯浊酒,满含同窗情谊;一张相片,留存校园美好;一个拥抱,满怀……开展万场助老活动,数字化适老及信息无障碍联盟成立今天是世界电信日,主题为面向老年人和实现健康老龄化的数字技术。5月17日,由工业和信息化部、内蒙古自治区人民政府主办,中国信息通信研究院、中国移动集团、蚂蚁集团承办的数字赋能老……关于环境的作文家乡环境美了我的家乡在孝义,是个小城,它虽然没有赛江南的美景,也没有杭州西湖的妖娆,但它却散发着一种平凡的自然美,随着社会的发展,家乡也在飞速地变化着,巨大的变化使原本美丽的小城更美了。……失败的游戏三年级作文游戏在生活中无处不在,今天,吴老师就跟我们做了个画方圆的游戏。我一听到这个游戏名称,觉得很奇怪。听吴老师讲后,我才知道这个游戏的。规则:左手右手各拿一支铅笔,同时用手里的笔在纸……六年级书信写给父母的一封信亲爱的爸爸妈妈:你们好!当我摊开这张叫感恩的的信纸,写下这一行行饱含真情的字,心中只有两个字:感恩。当我赤裸裸来到这个世界,体重不到十斤,身长仅有一尺。不会说……关于粤剧的作文粤剧,又称广东大戏或者大戏,广东传统戏曲之一,以下是小编收集的作文相关内容,欢迎查看!我家的粤剧迷说起我的外公,他的样子可特别了:60多岁的他,一点儿也不显得老,卷曲的头……写给未来的我三十岁的张开涛好!我是二十年前的你,你一定很惊讶吧!你不必惊讶。你就是我,我就是你,我们俩本来就是一个人,二十年后我就和你一样了。我给你写信,第一是要问未来世界到底……关于好与坏作文600字前几天,我去参加了由广州市少工委主办的少先队队干领导力集训营选拔活动。这次的选拔分为两个环节:笔试和答辩。笔试环节分成了选择题和开放式问答题,选择题主要是问我们眼中的领导应该具……纪海泊年青春,是道明媚的忧伤mdash;mdash;题记我降生到这个世界上十六年有十五年在迷路,剩下的一年我停在原地思考我为什么迷路。很不巧,青春期碰撞上了更年期。青春期的我和更……魔法小屋小学作文一架飞碟降落在广场上,里面走出了一个蓝胡子老爷爷。老爷爷手里捧着一个火柴盒那么大的木房子。他把小房子往地上一放,小房子一下就变得像真房子那么大了。这座小房子叫魔法小屋,有前门和……美丽的大金塔作文放假了!妈妈、爸爸带着我来到了芒市。刚来到芒市,我们就要去大金塔玩了,早就听说大金塔很美,这时我十分兴奋,心想大金塔到底有多么美呢?就这样,我好奇的踏上了去大金塔的路。来……和时间赛跑读后感作文350字三年级时,我读过林清玄的《和时间赛跑》。作者上三年级时,常把哥哥五年级的作业拿来做;有时一个暑假才能做完的作业,他十天就做完了。这些,都起因于外祖母去世后,爸爸对他说的一……
有关小学生演讲作文400字汇编7篇无论是在学校还是在社会中,大家都跟作文打过交道吧,根据写作命题的特点,作文可以分为命题作文和非命题作文。作文的注意事项有许多,你确定会写吗?下面是小编为大家整理的小学生演讲作文……中国电信和中国联通率先实现5G新通话互联互通4月26日,中国电信、中国联通全球率先在深圳、杭州、郑州、天津等城市开通基于双方共建共享5G网络并实现互联互通的5G新通话超清视频语音通话服务(VoNR:VoiceoverNe……以值得为题的记叙文800字作文一个人在世上做一些有值得的事,人的生命就会更有价值。请你以值得为题写一篇800字作文吧。下面品学网小编给大家带来以值得为题的记叙文优秀作文,供你参考。以值得为题的记叙文篇一……那一次我激动不已作文五年级时参加的朗诵比赛,我现在想起来还激动不已。以下是小编为大家准备的那一次我激动不已作文,仅供参考!那一次我激动不已作文【1】回忆,那一刻,我好想再次拥抱那让我最为激动……小学生寒假日记150字大全买东西今天我和妈妈一起去博爱路买东西。博爱路上人山人海。真是太多人了。我们到博爱路主要是买玩具,来的时候路过一个影碟店,还买了一些碟,是《喜羊羊与灰太狼》,还有《百变机兽》的碟,然后……校园的樟树450字作文一走进校园就可以看到一棵苍天大树,它就是我们喜欢的大樟树,校园的大樟树。大樟树在操场的左侧,它住在一个水泥砌成的小园子里。听从这所学校里退休的爷爷奶奶说,这棵大樟树已有一百多岁……感动五年级作文500字不知谁说过:因为有爱,所以才有感动。在我经历的所有事中,有一件事令我最感动。一天,我去动物园玩,看到一条铁索把一只老虎和一只大狗分开了,在大狗的旁边有一只小狗,看样子小狗……未来的房子的想象作文范文未来的世界有很多神奇的东西。其中我最喜欢的是未来的房子。这种房子它的外形是一个西瓜,里面有一间驾驶室。里面有控制机。有三个按键,一个是飞行,还有一个是地上跑,最后一个是水……我期待的青奥会小学作文范文2014年的青奥会,将在南京举行,作为南京市民的一份子,我感到无比的荣幸,也真诚的希望世界各地的朋友们来到南京做客。青奥会是一项专为年轻人设定的体育赛事,青奥会和奥运会相比最突……新技术曝光驾校教练要被取代?随着自动驾驶的普及,也将会淘汰掉不少传统行业固有职业,而驾校教练可能会首当其冲。近期,美国专利和商标申请中,通用汽车提交了一种自动驾驶汽车系统的设计,该系统旨在为驾校培训……改写小儿垂钓改写《小儿垂钓》在烈日当头的正午,诗人胡令能信步在乡间小道上。头顶是缕缕垂柳,小径两旁树木丛生,百草丰茂,好一处风水宝地。那小路附近静静的池水宛如明镜,池中几条小鱼在欢快……魅力威海作文500字早上四点,天未亮。匆匆坐上赶往威海的大巴,一路上昏昏欲睡。中午,匆匆吃过一顿不能称之为午饭的午饭,赶往第一个景点:赤山。赤山坐落于石岛港西北侧,方圆12。8平方公里……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网