找回密码
 立即注册
查看: 295|回复: 1

如何评价 Protobuf 的入门及使用?

[复制链接]
发表于 2023-5-21 15:44 | 显示全部楼层 |阅读模式
如何评价 Protobuf 的入门及使用?
发表于 2023-5-21 15:44 | 显示全部楼层
丁同舟,来自金蝶随手记技术团队。
1、引言

接上篇《金蝶随手记团队的Protobuf应用实践(原理篇)》,本文将以iOS端的Objective-C代码为例,图文并茂地向您菔救绾卧趇OS工程中快速使用Protobuf,希望对你有帮助。


2、系列文章
本文是系列文章中的第 9 篇,本系列总目录如下:

  • 《IM通讯协议专题学习(一):Protobuf从入门到精通,一篇就够!》
  • 《IM通讯协议专题学习(二):快速理解Protobuf的背景、原理、使用、优缺点》
  • 《IM通讯协议专题学习(三):由浅入深,从根上理解Protobuf的编解码原理》
  • 《IM通讯协议专题学习(四):从Base64到Protobuf,详解Protobuf的数据编码原理》
  • 《IM通讯协议专题学习(五):Protobuf到底比JSON快几倍?全方位实测!》
  • 《IM通讯协议专题学习(六):手把手教你如何在Android上从零使用Protobuf》(稍后发布..)
  • 《IM通讯协议专题学习(七):手把手教你如何在NodeJS中从零使用Protobuf》
  • 《IM通讯协议专题学习(八):金蝶随手记团队的Protobuf应用实践(原理篇)》
  • 《IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf》(* 本文)
另外:如果您还打算系统地学习IM开发,建议阅读《新手入门一篇就够:从零开发移动端IM》。
3、基本介绍




Protobuf(全称 Protocol buffers) 是 Google 提出的一种跨平台、多语言支持且开源的序列化数据格式。相对于类似的 XML 和 JSON,Protobuf 更为小巧、快速和简单。相对于传统的 XML 和 JSON, Protobuf 的优势主要在于:更加小、更加快,其语法目前分为proto2和proto3两种格式。
如果你没不了解Protobuf是什么,建议先阅读本系列的前几篇《Protobuf从入门到精通,一篇就够!》、《快速理解Protobuf的背景、原理、使用、优缺点》、《金蝶随手记团队的Protobuf应用实践(原理篇)》,本篇就不再重复介绍了。
目前 Google 官方的 Protobuf最新 release 版本为3.21.12,但本文写作时用的是3.5.1,以下截图都是基于此版本的环境搭建,如果你使用最新版本,差异并不大,因为只是小版本更新。
关于 Protobuf的使用可以查阅官方文档:https://developers.google.com/protocol-buffers/docs/overview,建议养成阅读文档的习惯。
4、准备工作

4.1环境要求

最低开发环境要求:

  • 1)Objective-C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X)
  • 2)Xcode 7.0 以上版本
注意:Protobuf 出于性能考虑没有使用 ARC,但在 ARC 下是可以使用的。
4.2下载安装

下载 Protobuf 代码包(https://github.com/protocolbuffers/protobuf/releases/tag/v21.12),因文章截图时用的是v3.5.1,所以我这里的为了保持一致选择的是 protobuf-objectivec-3.5.1.tar.gz,版本区别不大,建议依此类推。
4.3解压代码包

编译 Protobuf,这里可能需要安装部分工具:
$ brew install autoconf
$ brew install automake
$ brew install libtool
运行下面脚本进行编译:
$ ./autogen.sh
$ ./configure
$ make
$ makeinstall
检查protobuf是否安装成功:
$ protoc --version
如果成功打印版本号则安装成功:
libprotoc 3.5.1
5、在 iOS 中使用 Protobuf

5.1创建.proto文件

这里使用官方文档上的一份示例数据结构创建Person.proto:
syntax = "proto3";

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;

  enumPhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phone = 4;
}
使用命令行编译Person.proto为objective-c的文件,编译出来的文件为Person.pbobjc.h和Person.pbobjc.m:
protoc Person.proto --objc_out=./
5.2引入 Protobuf 运行时资源

Google 官方的文档提供了两种引入方式,但使用第一种的时候编译不能通过,所以这里选择了第二种。
具体就是:复制protobuf目录下的:objectivec/*.h, objectivec/google/protobuf/*.pbobjc.h, objectivec/google/protobuf/*.pbobjc.m, 以及除去 objectivec/GPBProtocolBuffers.m 后的objectivec/*.m。
这里直接用命令行操作。
首先进入protobuf下objectivec的目录:
$ cdprotobuf-3.5.1/objectivec
然后复制符合规则的文件到指定的工程目录下:
$mkdir~/ProtobufDemo/ProtocolBuffers~/ProtobufDemo/ProtocolBuffers/google~/ProtobufDemo/ProtocolBuffers/google/protobuf
$ cp*.h *.m ~/ProtobufDemo/ProtocolBuffers
$ cpgoogle/protobuf/*.pbobjc.h google/protobuf/*.pbobjc.m ~/ProtobufDemo/ProtocolBuffers/google/protobuf
注意:上面的命令并没有排除 GPBProtocolBuffers.m 文件,引入时需要手动排除。
现在把ProtocolBuffers目录下所有文件以及上面编译出来的 Person.pbobjc.hPerson.pbobjc.m 都引入到工程中。
现在工程目录结构大概是长这样:


注意:由于protobuf没有使用 ARC,因此需要为所有.m文件加上-fno-objc-arc来关闭 ARC。
结果如下:


提示:需要留意工程中的 Header Search Paths 要增加 $(PROJECT_DIR)/ProtocolBuffers(具体的路径视情况而定)
5.3直接引入 ProtocolBuffers 工程

如果觉得手动引入文件的方式过于复杂,可以直接引入ProtocolBuffers工程作为依赖项。
1)进入解压后的protobuf目录下,复制objective目录下的所有文件到ProtobufDemo/ProtocolBuffers目录下。
2)在ProtobufDemo工程中引入ProtocolBuffers_iOS工程:


3)在Build Phases中加入依赖关系并链接库:


4)引入Person.pbobjc.hPerson.pbobjc.m文件并为.m加上-fno-objc-arc
5)修改工程配置中部分路径为 $(PROJECT_DIR)/ProtocolBuffers
5.4运行测试

首先引入头文件:
#import "Person.pbobjc.h"
生成Person对象并进行编码和解码:
Person *p = [[Person alloc] init];
p.id_p = 1;
p.name = @"person1";
p.email = @"123@qq.com";

//encode
NSData*data = [p data];
NSLog(@"Protocol Buffers:\n%@\nData: %@\nData Length: %lu", p, data, data.length);

//decode
Person *newP = [[Person alloc] initWithData:data error:nil];
NSLog(@"Decoded: %@", newP);
运行程序,打印日志如下:
Protocol Buffers:
<;Person 0x60c0000da2b0>: {
    name: "person1"
    id: 1
    email: "123@qq.com"
}
Data: <0a077065 72736f6e 3110011a 0a313233 4071712e 636f6d>
Data Length: 23
Decoded: <;Person 0x6040000d9c90>: {
    name: "person1"
    id: 1
    email: "123@qq.com"
}
6、参考资料

[1] Protobuf 官方开发者指南(中文译版)
[2] Protobuf官方手册
[3] Protobuf从入门到精通,一篇就够!
[4] 如何选择即时通讯应用的数据传输格式
[5] 强列建议将Protobuf作为你的即时通讯应用数据传输格式
[6] APP与后台通信数据格式的演进:从文本协议到二进制协议
[7] 面试必考,史上最通俗大小端字节序详解
[8] 移动端IM开发需要面对的技术问题(含通信协议选择)
[9] 简述移动端IM开发的那些坑:架构设计、通信协议和客户端
[10] 理论联系实际:一套典型的IM通信协议设计详解
[11] 58到家实时消息系统的协议设计等技术实践分享
[12] 金蝶随手记团队的Protobuf应用实践(原理篇)
[13] 新手入门一篇就够:从零开发移动端IM

学习交流:
- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》
- 开源IM框架源码:https://github.com/JackJiang2011/MobileIMSDK(备用地址点此)
(本文已同步发布于:http://www.52im.net/thread-4133-1-1.html)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-4-27 15:21 , Processed in 0.102011 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表