纠纷奇闻社交美文家庭
投稿投诉
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

基于Protostuff实现的Netty编解码器

5月9日 龙凤殿投稿
  在设计netty的编解码器过程中,有许多组件可以选择,这里由于咱对Protostuff比较熟悉,所以就用这个组件了。由于数据要在网络上传输,所以在发送方需要将类对象转换成二进制,接收方接收到数据后,需要将二进制转换成类对象,由于这个操作在之前的文章中有讲解过:网络传输数据序列化工具Protostuff,所以可以翻看我之前的文章来查看具体的实践方法:publicclassSerializeUtil{
  privatestaticclassSerializeData{
  privateO
  }
  SuppressWarnings(unchecked)
  publicstaticbyte〔〕serialize(Objectobject){
  SerializeDataserializeDatanewSerializeData();
  serializeData。
  CSerializeDserializeDataClass(CSerializeD)serializeData。getClass();
  LinkedBufferlinkedBufferLinkedBuffer。allocate(10244);
  try{
  SSerializeDschemaRuntimeSchema。getSchema(serializeDataClass);
  returnProtostuffIOUtil。toByteArray(serializeData,schema,linkedBuffer);
  }catch(Exceptione){
  thrownewIllegalStateException(e。getMessage(),e);
  }finally{
  linkedBuffer。clear();
  }
  }
  SuppressWarnings(unchecked)
  TTdeserialize(byte〔〕data,CTclazz){
  try{
  SSerializeDschemaRuntimeSchema。getSchema(SerializeData。class);
  SerializeDataserializeDataschema。newMessage();
  ProtostuffIOUtil。mergeFrom(data,serializeData,schema);
  return(T)serializeData。
  }catch(Exceptione){
  thrownewIllegalStateException(e。getMessage(),e);
  }
  }
  }
  但是,上面只是普通的操作Util,如何让数据能够在netty上进行传输呢?
  在netty中,如果想发送数据出去,那么需要将数据转换成二进制,然后通过网络传送出去,他提供了MessageToByteEncoder的操作类,用户需要继承此类,然后实现encode方法就可以了。来看看我们如何将我们写好的SerializeUtil操作类集成进去:publicclassNettyMessageEncoderextendsMessageToByteENettyM{
  Override
  protectedvoidencode(ChannelHandlerContextctx,NettyMessagemsg,ByteBufout)throwsException{
  out。writeBytes(SerializeUtil。serialize(msg));
  }
  }
  如上代码所示,我们就准备好了一个基于Protostuff组件实现的编码类了。编码后的数据,被添加到ByteBuf缓冲区后,被发送出去。
  那么如何来实现解码器呢?publicclassNettyMessageDecoderextendsLengthFieldBasedFrameDecoder{
  publicNettyMessageDecoder(intmaxFrameLength,intlengthFieldOffset,intlengthFieldLength){
  super(maxFrameLength,lengthFieldOffset,lengthFieldLength);
  }
  Override
  publicObjectdecode(ChannelHandlerContextctx,ByteBufin)throwsException{
  try{
  byte〔〕dstBytesnewbyte〔in。readableBytes()〕;
  in。getBytes(in。readerIndex(),dstBytes);
  切记这里一定要用readBytes,不能用getBytes,否则会导致readIndex不能向后移动,从而导致nettydidnotreadanythingbutdecodedamessage。错误
  in。readBytes(dstBytes,0,in。readableBytes());
  NettyMessagenettyMessageSerializeUtil。deserialize(dstBytes,NettyMessage。class);
  returnnettyM
  }catch(Exceptione){
  System。out。println(exceptionwhendecoding:e);
  
  }
  }
  }
  如上代码所示。一般情况下,需要继承netty中的ByteToMessageDecoder操作类来实现,但是考虑到这样的话需要用户自己来处理粘包拆包问题,比较麻烦,所以我们就继承自netty中为我们准备好的LengthFieldBasedFrameDecoder来进行,由于此decoder具有处理粘包拆包的功能,而且其继承自ByteToMessageDecoder类,所以就省去了我们处理粘包拆包的逻辑。
  需要注意的是,在进行解码的过程中,我们首先需要从缓冲区读取数据到byte数组中,然后需要将readerIndex标记往后移动,如果读完后不移动的话,会报nettydidnotreadanythingbutdecodedamessage的错误,而且这个错误在你运行的时候并不会抛出来,非常隐蔽,要不是细细的调试客户端,根本不能发觉此错误的存在。
  所以从上面代码可以看出,ByteBuf。getBytes,只是单纯的读取缓存区数据,并不会将readerIndex后移。但是ByteBuf。readBytes则会将readerIndex后移。这点必须重视。
  最后,我们将这两个实现类放到handler执行容器中即可。channel。pipeline()。addLast(nettyMessageDecoder,newNettyMessageDecoder(10241024,4,4));
  channel。pipeline()。addLast(nettyMessageEncoder,newNettyMessageEncoder());
  channel。pipeline()。addLast(readTimeoutHandler,newReadTimeoutHandler(50));
  channel。pipeline()。addLast(loginAuthResponseHandler,newLoginAuthResponseHandler());
  channel。pipeline()。addLast(heartBeatHandler,newHeartBeatResponseHandler());
  最后启动服务,我们就可以看到我们的编解码器正常跑起来了:Loginisok:NettyMessage〔headerHeader〔crcCode1410399999,length0,sessionId0,type4,priority0,attachment{}〕〕
  Clientsendheartbeatmessagetoserver:NettyMessage〔headerHeader〔crcCode1410399999,length0,sessionId1344,type5,priority0,attachment{}〕〕
  Clientreceiveserverheartbeatmessage:NettyMessage〔headerHeader〔crcCode1410399999,length0,sessionId0,type6,priority0,attachment{}〕〕
  欢迎工作一到五年的Java工程师朋友们加入Java程序员开发:854393687
  群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用没有时间来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
投诉 评论 转载

基于Protostuff实现的Netty编解码器在设计netty的编解码器过程中,有许多组件可以选择,这里由于咱对Protostuff比较熟悉,所以就用这个组件了。由于数据要在网络上传输,所以在发送方需要将类对象转换成二进制……37Vue入门教程Vue项目本地Mock数据1。学习目标本小节我们将带大家学习如何在VueCli3初始化的项目中创建Mock数据。2。简介在日常开发中,接口的联调是非常普遍的。然而,有些时候接口并不会及时提供……本铃智速T8电动车评测搭载1200W专用电机,推背感十足在购买电动车时,对于部分用户来说,推背感十足的电动车一直备受欢迎。而对此,各大电动车企业也都在加大对这类车型的打造力度。而就在最近,本铃就推出了一款推背感十足的电动车智速T8。……未来的游戏方式?G胖握住脑机接口脑机接口技术始于1924年德国科学家汉斯伯杰看到电鳗发出电气,认为人类身上必然有相同的现象,于是他在后来发现人脑电波活动,并通过使用他发明脑电图描记法(EEG)来记录这些活动,……对提高高等数学教学效果的对策研究论文1高等数学的教学特点与学生的学习现状高等数学作为高职院校理工类各专业学习的基础课程,对学生而言,能否学好这门课以及通过这门课能否使自己各方面的能力得到提升,将会影响学生将……特斯拉澄清不实传言,6家中国媒体公开致歉,称制造传播不实信息近日,关于特斯拉的负面消息频繁出现在大众面前,随着舆论逐渐发酵,一些夸张虚假的传言也比比皆是,5月28日,特斯拉官方账号发文,对部分不实消息进行澄清,并附上了6家中国媒体的道歉……怎样解决域名和商标之间的冲突?【新网域名科普】在电子商务时代,域名不断高涨的商业价值,引起了域名和商标的冲突。此外,域名具有全球唯一性,但是多个商标权利主体可以同时拥有一个商标,这种冲突也时有发生。解……正念,此刻是一枝花2021年1月,新的一年刚刚开始,就遇到了一本好书《正念,此刻是一枝花》。正念是缘于佛教的智慧,这或许是我与佛的一种缘份。反思过去,我认为自已最大的问题是缺乏批判性思维,……家里想换智能门锁,老妈却接受不了,智能化越发普及,老人无所适智能锁一般有指纹、刷卡、密码、和钥匙开锁等几种方式,还具备开门即时信息推送、低电量提醒、防撬报警、开门联动灯光打开,开门联动场景等功能。我自己家里装的也是智能锁,然后配合……硕士论文提纲范例硕士论文提纲范例一摘要67目录911第1章绪论11211。1选题背景与研讨意义11121。1。1选题背景11121。1。2研讨意义12……传统媒体转型路径的有效探索城市服务商在受众流失、广告分流、骨干流失、传播力削弱四大因素的交织影响下,旧有的二次销售商业模式基本坍塌,传统媒体整体已经陷入困境的泥沼而难以自拔,而重建用户连接构建现代传播能力的尝试也……自食恶果?华为已终止1亿澳元研发投资,裁员千余人从2018年开始,澳大利亚政府开始禁止华为参与澳大利亚的5G建设,在这场移动网络的战争中,固然华为无法参与澳大利亚的5G建设,但澳大利亚也不会是赢家。据了解,华为已经在澳……
高品图像联手国家地理中文网华夏地理,深化战略合作查身份证入住酒店记录软件(免费查开宾馆记录查询)电波拉皮疼吗(电波拉皮有什么危害)退休生活的第一天这一座秘境,比宏村婺源更古朴,关键不要门票中秋小长假,合柴1972漫游艺术节,等你来打卡鳞次栉比是什么意思(鳞次栉比用来形容什么)点击广告挣钱(接广告赚钱)聚类分析软件(聚类分析法经典案例)2021年休旅车推荐,宝骏Valli潭柘寺的柘,原来如此!磨砂玻璃门图片(客厅最漂亮的推拉门图片)初中生步行街采风短篇作文淘宝达人主要展现渠道有什么合作要求父亲节的作文500字8篇小狗点点六年级作文生命早于地球亦或来自系外太空迪士尼自述一生的旅程从基层员工到全球超级之父普通新王登基!EDG夺冠英雄联盟S11总决赛,地标广告见证LPL你好旧时光iPhonese3曝光设计?全面屏和使用a15处理器历史上的今天中美签署我国入世双边协议释怀才是仇恨处理的正确方式,但要提防人心健康养生拔火罐要避免6个认知误区

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形