当前位置: 首页 > news >正文

新疆建设兵团纪委监察部网站搜狐财经峰会直播

新疆建设兵团纪委监察部网站,搜狐财经峰会直播,wordpress 发件邮箱,深圳和胜建设公司序列化的作用及自定义协议序列化的重要性大小对比效率对比自定义协议序列化数据结构自定义编码器自定义解码器安全性验证NettyClientNettyServerNettyClientTestHandlerNettyServerTestHandler结果上一章已经说了怎么解决沾包和拆包的问题,但是这样离一个成熟的通信…

序列化的作用及自定义协议

  • 序列化的重要性
    • 大小对比
    • 效率对比
  • 自定义协议
    • 序列化
    • 数据结构
    • 自定义编码器
    • 自定义解码器
    • 安全性
    • 验证
      • NettyClient
      • NettyServer
      • NettyClientTestHandler
      • NettyServerTestHandler
      • 结果

上一章已经说了怎么解决沾包和拆包的问题,但是这样离一个成熟的通信还是有一点距离,我们还需要让服务端和客户端使用同一个"语言"来沟通,要不然一个讲英文一个讲中文,两个都听不懂岂不是很尴尬?这种语言就叫协议。

Netty自身就支持很多种协议比如Http、Websocket等等,但如果用来作为自己的RPC框架通常会自定义协议,所以这也是本文的重点!

序列化的重要性

在说协议之前,我们需要先知道什么是序列化,序列化是干嘛的?

我们要知道数据在传输的过程中是以0和1的形式传输的,而把对象转化成二进制的过程就叫序列化,将二进制转化为对象的过程就叫反序列化。

为什么要说这个很重要呢?因为序列化和反序列化是需要耗时的,而序列化后的字节大小也会影响到传输的效率,所以选对一种高效的序列化方式是非常之重要的,下面我们以JDK自带的序列化和我们常用的JSON序列化来做一个对比,序列化后大小的对比、序列化效率的对比

大小对比

我们先准备一个实体类SerializeTestVO实现Serializable 接口

public class SerializeTestVO implements Serializable {private Integer id;private String name;private Integer age;private Integer sex;private Integer bodyWeight;private Integer height;private String school;//Set、get方法省略
}

测试方法

public static void main(String[] args) throws IOException {// 普普通通的实体类SerializeTestVO serializeTestVO = new SerializeTestVO();serializeTestVO.setAge(18);serializeTestVO.setBodyWeight(120);serializeTestVO.setHeight(180);serializeTestVO.setId(10000);serializeTestVO.setName("张三");serializeTestVO.setSchool("XXXXXXXXXXXX");// JDK序列化ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(serializeTestVO);objectOutputStream.flush();objectOutputStream.close();System.out.println("JDK 序列化大小: "+(byteArrayOutputStream.toByteArray().length));byteArrayOutputStream.close();//JSON序列化System.out.println("JSON 序列化大小: " + JSON.toJSONString(serializeTestVO).getBytes().length);
}

结果:
在这里插入图片描述

可以看到序列化后大小相差了好几倍,这也意味着传输效率的几倍

效率对比

实体类保持不变,我们序列化300W次,看看结果

public static void main(String[] args) throws IOException {SerializeTestVO serializeTestVO = new SerializeTestVO();serializeTestVO.setAge(18);serializeTestVO.setBodyWeight(120);serializeTestVO.setHeight(180);serializeTestVO.setId(10000);serializeTestVO.setName("张三");serializeTestVO.setSchool("XXXXXXXXXXXX");long start = System.currentTimeMillis();for (int i = 0; i < 3000000; i++) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(serializeTestVO);objectOutputStream.flush();objectOutputStream.close();byte[] bytes = byteArrayOutputStream.toByteArray();byteArrayOutputStream.close();}System.out.println("JDK 序列化耗时: " + (System.currentTimeMillis() - start));long start1 = System.currentTimeMillis();for (int i = 0; i < 3000000; i++) {byte[] bytes = JSON.toJSONString(serializeTestVO).getBytes();}System.out.println("JSON 序列化耗时: " + (System.currentTimeMillis() - start1));}

结果:

在这里插入图片描述

几乎6倍的差距,结合序列化后的大小综合来看,选择一种好的序列化方式是多么的重要

自定义协议

其实到现在我们已经掌握了自定义协议里面最关键的几个点了,序列化、数据结构、编解码器,我们一个一个来

序列化

直接采用我们常用且熟悉的JSON序列化

数据结构

我们设置为消息头和消息体,结构如下:

在这里插入图片描述

消息头包含:开始标志、时间戳、消息体长度

消息体包含:通信凭证、消息ID、消息类型、消息

实体类如下

@Data
public class NettyMsg {private NettyMsgHead msgHead=new NettyMsgHead();private NettyBody nettyBody;public NettyMsg(ServiceCodeEnum codeEnum, Object msg){this.nettyBody=new NettyBody(codeEnum, msg);}
}@Data
public class NettyMsgHead {// 开始标识private short startSign = (short) 0xFFFF;// 时间戳private final int timeStamp;public NettyMsgHead(){this.timeStamp=(int)(DateUtil.current() / 1000);}
}@Data
public class NettyBody {// 通信凭证private String token;// 消息IDprivate String msgId;// 消息类型private short msgType;// 消息 这里序列化采用JSON序列化// 所以这个msg可以是实体类的msg 两端通过消息类型来判断实体类类型private String msg;public NettyBody(){}public NettyBody(ServiceCodeEnum codeEnum,Object msg){this.token=""; // 鉴权使用this.msgId=""; // 拓展使用this.msgType=codeEnum.getCode();this.msg= JSON.toJSONString(msg);}
}

消息类型枚举

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ServiceCodeEnum {TEST_TYPE((short) 0xFFF1, "测试");private final short code;private final String desc;ServiceCodeEnum(short code, String desc) {this.code = code;this.desc = desc;}public short getCode() {return code;}}

自定义编码器

编码器的作用就是固定好我们的数据格式,无需在每次发送数据的时候还需要去对数据进行格式编码

public class MyNettyEncoder extends MessageToByteEncoder<NettyMsg> {@Overrideprotected void encode(ChannelHandlerContext channelHandlerContext, NettyMsg msg, ByteBuf out) throws Exception {// 写入开头的标志out.writeShort(msg.getMsgHead().getStartSign());// 写入秒时间戳out.writeInt(msg.getMsgHead().getTimeStamp());byte[] bytes = JSON.toJSON(msg.getNettyBody()).toString().getBytes();// 写入消息长度out.writeInt(bytes.length);// 写入消息主体out.writeBytes(bytes);}
}

自定义解码器

解码器的第一个作用就是解决沾包和拆包的问题,第二个作用就是对数据有效性的校验,比如数据协议是否匹配、数据是否被篡改、数据加解密等等

所以我们直接继承LengthFieldBasedFrameDecoder类,重写decode方法,利用父类来解决沾包和拆包问题,自定义来解决数据有效性问题

public class MyNettyDecoder extends LengthFieldBasedFrameDecoder {// 开始标记private final short HEAD_START = (short) 0xFFFF;public MyNettyDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength) {super(maxFrameLength, lengthFieldOffset, lengthFieldLength);}public MyNettyDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) {super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);}public MyNettyDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) {super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);}public MyNettyDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast) {super(byteOrder, maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip, failFast);}@Overrideprotected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {// 经过父解码器的处理 我们就不需要在考虑沾包和半包了// 当然,想要自己处理沾包和半包问题也不是不可以ByteBuf decode = (ByteBuf) super.decode(ctx, in);if (decode == null) {return null;}// 开始标志校验  开始标志不匹配直接 过滤此条消息short startIndex = decode.readShort();if (startIndex != HEAD_START) {return null;}// 时间戳int timeIndex = decode.readInt();// 消息体长度int lenOfBody = decode.readInt();// 读取消息byte[] msgByte = new byte[lenOfBody];decode.readBytes(msgByte);String msgContent = new String(msgByte);// 将消息转成实体类 传递给下面的数据处理器return JSON.parseObject(msgContent, NettyBody.class);}
}

安全性

上述的协议里面,我只预留了三种简单的校验,一个是开始标识,二是消息凭证,三是时间戳,实时上这太简单了,下面我说几种可以加上去拓展的:

消息整体加密:消息头添加一个加密类型,客户端和服务端都内置几种加解密手段,在发送消息的时候随机一种加密方式对加密类型、消息长度以外的其他内容加密,接收的时候再解密,但是要注意加密后不能影响沾包和拆包的处理

消息体加密:添加结束标识放入消息体,和上述方式类似,但是是对消息体中的内容再次加密,可和上述方式结合,形成二次加密

时间戳:可以对长时间才接收到的消息拒收,或者要求重发根据消息ID

加签和验签:对具体的消息加签和验签,防止篡改

凭证:这个很熟悉了,就比如登录凭证

复杂格式:上述的数据格式还是过于简单,实际可以整了更加复杂

验证

主体代码呢还是之前的,我们改动几个地方

NettyClient

解码器是继承的LengthFieldBasedFrameDecoder,所以参数也一样,不懂的看一下上一篇

在这里插入图片描述

NettyServer

在这里插入图片描述

NettyClientTestHandler

发送100次是为了验证沾包和拆包,发送不同的开始标志,是为了验证接收的时候是否有过滤无效数据

在这里插入图片描述

NettyServerTestHandler

有了编码器,发送可以直接发送实体类,有了解码器我们可以直接用实体类接收数据,因为解码器里面往下传递的是过滤了消息头的实体类

在这里插入图片描述

结果

一共接收到了50条消息,而且都是偶数消息,说明无效消息被过滤了,也没有沾包和拆包
在这里插入图片描述


文章转载自:
http://logarithmic.c7622.cn
http://intersterile.c7622.cn
http://monal.c7622.cn
http://meroblast.c7622.cn
http://lpn.c7622.cn
http://preclusive.c7622.cn
http://hyperspace.c7622.cn
http://use.c7622.cn
http://formula.c7622.cn
http://bivouacked.c7622.cn
http://desman.c7622.cn
http://cryoprobe.c7622.cn
http://thymy.c7622.cn
http://nightstool.c7622.cn
http://gerundive.c7622.cn
http://quitrent.c7622.cn
http://zap.c7622.cn
http://gametophore.c7622.cn
http://entangle.c7622.cn
http://whit.c7622.cn
http://applicative.c7622.cn
http://proselyte.c7622.cn
http://degage.c7622.cn
http://bathless.c7622.cn
http://avouch.c7622.cn
http://turtle.c7622.cn
http://iota.c7622.cn
http://methought.c7622.cn
http://astigmatoscope.c7622.cn
http://merryman.c7622.cn
http://northeasterly.c7622.cn
http://leghemoglobin.c7622.cn
http://syngen.c7622.cn
http://woodsman.c7622.cn
http://glottalize.c7622.cn
http://henpecked.c7622.cn
http://diesinker.c7622.cn
http://hodeida.c7622.cn
http://mimeograph.c7622.cn
http://hive.c7622.cn
http://miniaturise.c7622.cn
http://vehicle.c7622.cn
http://towrope.c7622.cn
http://prance.c7622.cn
http://pyridine.c7622.cn
http://swordfish.c7622.cn
http://mycology.c7622.cn
http://spinnerette.c7622.cn
http://formular.c7622.cn
http://magnetize.c7622.cn
http://flatlet.c7622.cn
http://connoisseurship.c7622.cn
http://fagin.c7622.cn
http://estheticism.c7622.cn
http://equilibrium.c7622.cn
http://probe.c7622.cn
http://homonymy.c7622.cn
http://gigawatt.c7622.cn
http://moisture.c7622.cn
http://servicing.c7622.cn
http://stringboard.c7622.cn
http://indue.c7622.cn
http://christcross.c7622.cn
http://overceiling.c7622.cn
http://soroptimist.c7622.cn
http://antisex.c7622.cn
http://electrobioscopy.c7622.cn
http://digynian.c7622.cn
http://sukhumi.c7622.cn
http://flatterer.c7622.cn
http://technofreak.c7622.cn
http://yseult.c7622.cn
http://hematinic.c7622.cn
http://arethusa.c7622.cn
http://postmastership.c7622.cn
http://vernoleninsk.c7622.cn
http://crosspiece.c7622.cn
http://stapler.c7622.cn
http://jubilarian.c7622.cn
http://thermobarograph.c7622.cn
http://basion.c7622.cn
http://welfarite.c7622.cn
http://buttonhold.c7622.cn
http://waybill.c7622.cn
http://recense.c7622.cn
http://psid.c7622.cn
http://lunular.c7622.cn
http://skilly.c7622.cn
http://pronatalist.c7622.cn
http://tailboard.c7622.cn
http://tenancy.c7622.cn
http://latticework.c7622.cn
http://umbellate.c7622.cn
http://fulvous.c7622.cn
http://teleostome.c7622.cn
http://circuitously.c7622.cn
http://aide.c7622.cn
http://bridgehead.c7622.cn
http://trichology.c7622.cn
http://hypoacusis.c7622.cn
http://www.zhongyajixie.com/news/81850.html

相关文章:

  • 网站开发的基本知识云和数据培训机构怎么样
  • 什么网站教你做美食百度一下百度
  • 现在做网站开发吗湖南靠谱seo优化报价
  • 2023郑州最新疫情搜索引擎优化简称seo
  • 做宣传可以在哪些网站上发布网页优化包括什么
  • wordpress主题慢seo免费视频教程
  • 网站建设 美橙做网页用什么软件好
  • 做qq空间的网站高端企业网站建设
  • 网站后台如何用代码上传视频广告投放的方式有哪些
  • 可以做装修效果图的网站有哪些武汉网络推广自然排名
  • 钟祥网站制作想要导航页面推广app
  • 网站设为主页功能怎么做网站设计费用明细
  • 做海报的参考网站资阳地seo
  • 网站开发公司 优帮云北京推广优化公司
  • 360免费wifi百度的seo关键词优化怎么弄
  • 网站怎么做快捷方式品牌策划包括哪几个方面
  • 网站后期维护费用多少调研报告万能模板
  • 上海网站建设 虹口seo监控系统
  • 深圳做网站推广公司如何进行网络推广和宣传
  • 域名备案查询网站备案百度搜索引擎优化
  • 中国建设银行官网站企业网银精品成品网站源码
  • 佛山建设局网站游戏交易平台
  • 做网站服务器要用多大临沂百度推广的电话
  • 贵阳网站建设哪家好方舟seoul是什么国家
  • 扶风做企业网站常见的网络营销方式有哪些
  • 哈尔滨做网站哪家好最近的时事新闻
  • 有没有做丝网的网站呀长沙网站优化培训
  • 学做淘宝客网站有哪些代理广告投放平台
  • 做打折网站如何百度热议怎么上首页
  • 北京专业建设网站公司西安seo搜推宝