Proto3序列化协议

2024-09-03 13:58
文章标签 协议 序列化 proto3

本文主要是介绍Proto3序列化协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Proto3序列化协议

简介

对于互联网应用来说,客户端-客户端、客户端-服务端之间需要数据的交互,其数据传输是二进制流的方式在互联网上传输,因为需要一种手段将数据对象编码为一种可以在网络上传输的二进制流,这个过程就叫做序列化。同样的,客户端在收到二进制流需要解码出数据,这个过程叫反序列。

简单理解就是序列化就是按照某种编码方式将数据转换为二进制流以方便在网络上传输,同时这种编码方式是可逆的和可理解的。

按照上述定义不难理解,json也是一种序列化的一种方式,将对象编码为字符串(二进制)进行传输。

同样的proto3是google推出的一种序列化框架。全称是Protocol Buffers。

其具有以下特点:

  • 小:生成的字节流采用了各种压缩方式,相对xml和json这类文件更小。

  • 快:编解码基本都是位运算,也没有复杂的嵌套关系,速度快。

  • 安全:这里的安全,是指protobuf没有把字段名写入到字节流里,只是写入了字段号信息。另外,相对于xml和json来说,因为被编码成二进制,破解成本增大。

编码方式

我们定义了一个Person的消息类型,那protobuf是怎么把它编码成二进制的呢?其实它是把message转成一系列的key-value,key就是字段号,value就是字段值,大概这样子存:

message Person {string name = 1;int32  id   = 2;
}

=1,=2称为tag, 唯一标识每个元素,其值不可重复,其中tag在1-15之间编码为一个字节,大于15字节将需要多个字节进行编码,因此作为优化手段,1-15 tag多用户经常出现的元素,15+的tag用于不长出现或者可选的元素,此外,对于repeated类型的message,其每个元素都需要一个tag,所以repeated适合用小于15的tag。

对于上述的定义,其会按照[tag1][value1][tag2][value2][tag3][value3]...的方式进行编码,

解码时,会从左往右解析每一个key-value,假如遇到某个key-value无法解析了,那么就直接跳过,不会影响到其它key-value的解析,因此如果你加了新字段,生成字节流,然后用旧版本解析,这时它还是能够解析出旧版本的字段的,新字段只是被忽略而已,这就是protobuf的向后兼容。

需要注意,一旦发布proto协议,其tag值就不能修改,新增字段只能使用未使用的tag(即使删除的tag也不可以),删除一个字段可以,解码时如果没有该字段会默认填充默认值,如果删除删除一个字段,最好采用reversed标识使用过的tag值,避免后续误使用旧的tag值。

官方建议:

  • xxx.proto一行最多80字符

  • 2个空格缩进

  • 字符串用双引号

  • 文件名小写、_组成,如lower_snake_case.proto

  • message 定义要驼峰式且首字母大写

message SongServiceRequest {required string song_name = 1;
}
  • 如果成员变量包含数组,应采用 song_name1 而不是 song_name_1

  • 对于repeated类型应该用复数,如repeated string keys = 1;

//类型是大写+驼峰式
enum FooBar {FOO_BAR_UNSPECIFIED = 0;  // 0值定义UNSPECIFIEDFOO_BAR_FIRST_VALUE = 1;  //值是全大写常量定义FOO_BAR_SECOND_VALUE = 2;
}
  • 对于Services定义
  //驼峰+大写service FooService {rpc GetSomething(FooRequest) returns (FooResponse); //函数名以驼峰+首字母大写}

这篇关于Proto3序列化协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133154

相关文章

Java序列化之serialVersionUID的用法解读

《Java序列化之serialVersionUID的用法解读》Java序列化之serialVersionUID:本文介绍了Java对象的序列化和反序列化过程,强调了serialVersionUID的作... 目录JavChina编程a序列化之serialVersionUID什么是序列化为什么要序列化serialV

idea-java序列化serialversionUID自动生成方式

《idea-java序列化serialversionUID自动生成方式》Java的Serializable接口用于实现对象的序列化和反序列化,通过将对象转换为字节流来存储或传输,实现Serializa... 目录简介实现序列化serialVersionUID配置使用总结简介Java.io.Seripyth

java反序列化serialVersionUID不一致问题及解决

《java反序列化serialVersionUID不一致问题及解决》文章主要讨论了在Java中序列化和反序列化过程中遇到的问题,特别是当实体类的`serialVersionUID`发生变化或未设置时,... 目录前言一、序列化、反序列化二、解决方法总结前言serialVersionUID变化后,反序列化失

HTTP 与 SpringBoot 参数提交与接收协议方式

《HTTP与SpringBoot参数提交与接收协议方式》HTTP参数提交方式包括URL查询、表单、JSON/XML、路径变量、头部、Cookie、GraphQL、WebSocket和SSE,依据... 目录HTTP 协议支持多种参数提交方式,主要取决于请求方法(Method)和内容类型(Content-Ty

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Java对接MQTT协议的完整实现示例代码

《Java对接MQTT协议的完整实现示例代码》MQTT是一个基于客户端-服务器的消息发布/订阅传输协议,MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛,:本文主要介绍Ja... 目录前言前置依赖1. MQTT配置类代码解析1.1 MQTT客户端工厂1.2 MQTT消息订阅适配器1.

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red