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

相关文章

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

如何配置Spring Boot中的Jackson序列化

《如何配置SpringBoot中的Jackson序列化》在开发基于SpringBoot的应用程序时,Jackson是默认的JSON序列化和反序列化工具,本文将详细介绍如何在SpringBoot中配置... 目录配置Spring Boot中的Jackson序列化1. 为什么需要自定义Jackson配置?2.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

Django序列化中SerializerMethodField的使用详解

《Django序列化中SerializerMethodField的使用详解》:本文主要介绍Django序列化中SerializerMethodField的使用,具有很好的参考价值,希望对大家有所帮... 目录SerializerMethodField的基本概念使用SerializerMethodField的

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。