Protobuf 小试牛刀 (3)

10、Any
Any类型允许包装任意的message类型,可以通过pack()和unpack()(方法名在不同的语言中可能不同)方法打包/解包:

import "google/protobuf/any.proto"; message Response { google.protobuf.Any data = 1; }

PHP开发的同学可能觉得Any没必要,因为数组里任何类型都可以放,但是对于强类型语言,数组里的值类型必须是一致的,使用Any类型可以解决这个问题。Any相当于把值包装了一层,这样都是Any类型。

11、服务定义

service UserService { // 方法名 方法参数 返回值 rpc GetUser(Request) returns (Response); }

这相当于定义了一个类,里面有一个对外的GetUser()方法。这个通常用于定义RPC服务,与gRPC结合使用。

12、从.proto文件生成了什么?
当用protocol buffer编译器来运行.proto文件时,编译器将生成所选择语言的代码,这些代码可以操作在.proto文件中定义的消息类型,包括获取、设置字段值,将消息序列化到一个输出流中,以及从一个输入流中解析消息。

PHP:每一个Message或者Enum生成一个类,另外还会生成GPBMetadata。

C++:编译器会为每个.proto文件生成一个.h文件和一个.cc文件,.proto文件中的每一个消息有一个对应的类。

Java:编译器为每一个消息类型生成了一个.java文件,以及一个特殊的Builder类(该类是用来创建消息类接口的)。

Python:Python编译器为.proto文件中的每个消息类型生成一个含有静态描述符的模块,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类。

go:编译器会位每个消息类型生成了一个.pd.go文件。

Ruby:编译器会为每个消息类型生成了一个.rb文件。

Objective-C:编译器会为每个消息类型生成了一个pbobjc.h文件和pbobjcm文件,.proto文件中的每一个消息有一个对应的类。

C#:编译器会为每个消息类型生成了一个.cs文件,.proto文件中的每一个消息有一个对应的类。

其它 IDE插件

1、JetBrains PhpStorm 可以在插件里找到Protobuf安装,重启IDE后就支持proto格式语法了。

2、VScode 在扩展里搜索 Protobuf,安装即可。

3、protobuf的 php 扩展类在ide中没有提示,可将https://github.com/protocolbuffers/protobuf/tree/master/php/src 目录下载到本地,将此目录加到ide的include_path中即可。

常见问题

1、 protoc 编译输出php文件时遇到一个错误:protobuf google.protobuf.Any not found。
原因:安装proto的时候没有把include/google复制到/usr/include/。
解决:重新下载protoc-3.8.0-linux-x86_64.zip并将解压后的include/google复制到/usr/include/。

2、Mac下执行phpize报如下错误:

grep: /usr/include/php/main/php.h: No such file or directory grep: /usr/include/php/Zend/zend_modules.h: No such file or directory grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory

解决方法:

xcode-select --instal 参考

1、protoc2 与 protoc3 区别 - 简书
https://www.jianshu.com/p/cdedcf696e9e
2、gRPC之proto语法 - 简书
https://www.jianshu.com/p/da7ed5914088
3、Protobuf3语法详解 - 望星辰大海 - 博客园
https://www.cnblogs.com/tohxyblog/p/8974763.html

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzdgx.html