nodejs protocolbuffer_在 NodeJS 中玩转 Protocol Buffer

在 NodeJS 中玩转 Protocol Buffer

腾讯IVWEB团队发表于腾讯IVWEB团队的专栏订阅

1.3K

在这篇文章中:

  • Protocol Buffer入门教程
  • Protocol Buffer是个什么鬼?
  • NodeJS开发者为何要跟Protocol Buffer打交道
  • 在NodeJS中实践Protocol Buffer协议
  • 选择支持protobuf的NodeJS第三方模块
  • 一个栗子
  • 再举一个栗子
  • 其他高级特性
  • 总结一下
  • 优点
  • 缺点

Protocol Buffer是个什么鬼?

Protocol Buffer(下文简称protobuf)是Google提供的一种数据序列化协议,下面是我从网上找到的Google官方对protobuf的定义:

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

NodeJS开发者为何要跟Protocol Buffer打交道

作为JavaScript开发者,对我们最友好的数据序列化协议当然是大名鼎鼎的JSON啦!我们本能的会想protobuf是什么鬼?还我JSON!

这就要说到protobuf的历史了。

Protobuf由Google出品,08年的时候Google把这个项目开源了,官方支持C++,Java,C#,Go和Python五种语言,但是由于其设计得很简单,所以衍生出很多第三方的支持,基本上常用的PHP,C,Actoin Script,Javascript,Perl等多种语言都已有第三方的库。

由于protobuf协议相较于之前流行的XML更加的简洁高效(后面会提到这是为什么),因此许多后台接口都是基于protobuf定制的数据序列化协议。而作为NodeJS开发者,跟C++或JAVA编写的后台服务接口打交道那是家常便饭的事儿,因此我们很有必要掌握protobuf协议。

为什么说使用使用类似protobuf的二进制协议通信更好呢?

  1. 二进制协议对于电脑来说更容易解析,在解析速度上是http这样的文本协议不可比拟的。
  2. 有tcp和udp两种选择,在一些场景下,udp传输的效率会更高。
  3. 在后台开发中,后台与后台的通信一般就是基于二进制协议的。甚至某些native app和服务器的通信也选择了二进制协议(例如腾讯视频)。但由于web前端的存在,后台同学往往需要特地开发维护一套http接口专供我们使用,如果web也能使用二进制协议,可以节省许多后台开发的成本。

在大公司,最重要的就是优化效率、节省成本,因此二进制协议明显优于http这样的文本协议。

下面举两个简单的例子,应该有助于我们理解protobuf。

在NodeJS中实践Protocol Buffer协议

选择支持protobuf的NodeJS第三方模块

  • protobuf.js
93655546098dc023e944646b0c66b46b.png
  • Google protobuf js
d9f2c389dffa48679c0ad980c479fa10.png
  • protocol-buffers
b43eb8feba414f2c5de8389edc7504ac.png

根据star数和文档完善程度两方面综合考虑,我们决定选择protobuf.js。

一个栗子

517954ef3d947e8cf4fc60425c631080.png

我打算使用 Protobuf 和NodeJS开发一个十分简单的例子程序。

该程序由两部分组成。第一部分被称为 Writer,第二部分叫做 Reader。

Writer 负责将一些结构化的数据写入一个磁盘文件,Reader 则负责从该磁盘文件中读取结构化数据并打印到屏幕上。

准备用于演示的结构化数据是 HelloWorld,它包含两个基本数据:

  • ID,为一个整数类型的数据
  • Str,这是一个字符串

书写.proto文件

首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf 的术语中,结构化数据被称为 Message。proto 文件非常类似 java 或者 C 语言的数据定义。代码清单 1 显示了例子应用中的 proto 文件内容。

清单 1. proto 文件

package lm; message helloworld {  required int32 id = 1; // ID  required string str = 2; // str  optional int32 opt = 3; //optional field }

一个比较好的习惯是认真对待 proto 文件的文件名。比如将命名规则定于如下:

packageName.MessageName.proto

在上例中,package 名字叫做 lm,定义了一个消息 helloworld,该消息有三个成员,类型为 int32 的 id,另一个为类型为 string 的成员 str。opt 是一个可选的成员,即消息中可以不包含该成员。1、2、3这几个数字是这三个字段的唯一标识符,这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变。

编译 .proto 文件

我们可以使用protobuf.js提供的命令行工具来编译 .proto 文件

用法:

# pbjs  [options] [> outFile]

我们来看看options:

 --help, -h Show help [boolean] 查看帮助 --version, -v Show version number [boolean] 查看版本号 --source, -s Specifies the source format. Valid formats are: json Plain JSON descriptor proto Plain .proto descriptor指定来源文件格式,可以是json或proto文件 --target, -t Specifies the target format. Valid formats are: amd Runtime structures as AMD module commonjs Runtime structures as CommonJS module js Runtime structures json Plain JSON descriptor proto Plain .proto descriptor指定生成文件格式,可以是符合amd或者commonjs规范的js文件,或者是单纯的js/json/proto文件。 --using, -u Specifies an option to apply to the volatile builder loading the source, e.g. convertFieldsToCamelCase. --min, -m Minifies the output. [default: false] 压缩生成文件 --path, -p Adds a directory to the include path. --legacy, -l Includes legacy descriptors from google/protobuf/ if explicitly referenced. [default: false] --quiet, -q Suppresses any informatory output to stderr. [default: false] --use, -i Specifies an option to apply to the emitted builder utilized by your program, e.g. populateAccessors. --exports, -e Specifies the namespace to export. Defaults to export the root namespace. --dependency, -d Library dependency to use when generating classes. Defaults to 'protobufjs' for CommonJS, 'ProtoBuf' for AMD modules and 'dcodeIO.ProtoBuf' for classes.

重点关注- -target就好,由于我们是在Node环境中使用,因此选择生成符合commonjs规范的文件,命令如下:

# ./pbjs ../../lm.message.proto -t commonjs > ../../lm.message.js

得到编译后的符合commonjs规范的js文件:

module.exports = require("protobufjs").newBuilder({})['import']({ "package": "lm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值