protobufjs 使用方法

image

protobuf.js是一個純JavaScript實現(xiàn),支持Node.js和瀏覽器的TypeScript棚愤,它容易使用速度快速骏庸,可以直接反射.proto文件髓涯,不需要生成任何文件袒啼。

protobuf.js是基于ByteBuffer.js的Protocol Buffers純JavaScript實現(xiàn),主要功能是解析.proto文件,構(gòu)建Message類瘤泪,編碼解碼灶泵。

window 下

1,下載用來生成web js文件的工具

protoc-gen-grpc-web

下地地址:https://github.com/grpc/grpc-web/releases

選擇:protoc-gen-grpc-web-1.3.1-windows-x86_64.exe 即可

下載完成后改名為protoc-gen-grpc-web.exe并移動到項目里,和proto文件存放在同一目錄下

2,下載protoc.exe執(zhí)行程序下載地址protoc.exe

https://github.com/protocolbuffers/protobuf/releases
選擇protoc-3.20.1-win32.zip
下載后解壓就行对途,然后把bin文件夾里面的protoc.exe路徑加入到環(huán)境變量赦邻。
找到環(huán)境變量,系統(tǒng)變量->Path->新建->復(fù)制bin文件夾的路徑实檀,然后一直點確定退出即可惶洲。
把protoc.exe拷貝到C:\Windows\System32路徑下。

調(diào)用cmd膳犹,輸入protoc發(fā)現(xiàn)提示missing input file恬吕,證明已經(jīng)可以使用了。

3, 進入到proto文件所在目錄的cmd執(zhí)行命令

protoc -I=./ ./engine_service.proto --js_out=import_style=commonjs:./ --plugin=protoc-gen-grpc=./protoc-gen-grpc-web.exe --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./
該命令是將engine_service.proto文件生成js文件
生成其他文件只需替換文件名即可
示例:


image.png

engine_service.proto文件生成了兩個對應(yīng)的js文件

node 安裝

下載安裝protobufjs

https://github.com/protobufjs/protobuf.js

查看protobufjs候選版本

$ npm view protobufjs versions

使用NPM全局安裝protobufjs

$ npm i -g protobufjs

protobuf.js 依賴 long.js须床、bytebuffer.js

創(chuàng)建.proto文件

msg.proto

syntax = "proto3";

package ns;

message Login {
    string name = 1;
    string pwd = 2;
}
message Address{
  required string province = 1;
  required string city = 2;
  required string country = 3;
}

這個是使用cim框架時候?qū)嶋H使用中有map類

syntax = "proto3";
package com.model.proto;
option java_outer_classname="ReplyBodyProto";

message Model {
   string key = 1;
   string code = 2;
   string message = 3;
   int64 timestamp =4;
   map<string,string> data =5;
   
}
     

轉(zhuǎn)換

在命令行模式下铐料,pbjs命令用于在文件格式之間轉(zhuǎn)換,并可以生成靜態(tài)代碼豺旬。

$ pbjs

protobuf.js v6.7.0 CLI for JavaScript
在文件格式之間轉(zhuǎn)換并生成靜態(tài)代碼
  -t, --target 指定目標(biāo)格式钠惩,可以接受需要自定義目標(biāo)的路徑。
                   json          JSON
                   json-module   JSON表示為模塊
                   proto2        Protocol Buffers, Version 2
                   proto3        Protocol Buffers, Version 3
                   static        無反射的靜態(tài)代碼(本身不起作用)
                   static-module 無反射模塊的靜態(tài)代碼
  -p, --path 將某個目錄添加到包含路徑中
  -o, --out 保存文件而非寫入到標(biāo)準(zhǔn)輸出
  --sparse 只導(dǎo)出從主文件引用的類型(實驗)
  僅限模塊目標(biāo):
  -w, --wrap       指定要使用的包裝器族阅,可接受需要自定義包裝器的路徑篓跛。
                   default   默認(rèn)包裝器支持CommonJS與AMD標(biāo)準(zhǔn)
                   commonjs  CommonJS包裝器
                   amd       AMD包裝器
                   es6       ES6包裝器
                   closure   添加到全局protobuf的protobuf.roots上的閉包
  --dependency     指定protobuf版本,可接受有效的模塊ID坦刀。
  -r, --root       指定備用的protobuf.roots名稱
  -l, --lint       Linter配置愧沟,默認(rèn)protbuf.js兼容規(guī)則:
                   eslint-disable block-scoped-var, id-length, 
                   no-control-regex, no-magic-numbers, no-prototype-builtins, 
                   no-redeclare, no-shadow, no-var, sort-vars
  --es6            啟用ES6語法
  僅限原始源:
  --keep-case      保留字段大小寫而非是轉(zhuǎn)換為駝峰大小寫
  僅限靜態(tài)目標(biāo):
  --no-create      不生成用于反射兼容性的創(chuàng)建函數(shù).
  --no-encode      不生成編碼函數(shù).
  --no-decode      不生成解碼函數(shù).
  --no-verify      不生成驗證函數(shù).
  --no-convert     不生成轉(zhuǎn)換函數(shù)
  --no-delimited   不生成風(fēng)格的編碼/解碼函數(shù).
  --no-beautify    不美化生成的代碼.
  --no-comments    不輸出任何JSDoc注釋.
  --force-long     強制對s-/u-/int64和s-/fixed64字段使用Long
  --force-number   強制對s-/u-/int64和s-/fixed64字段使用number
  --force-message  強制使用消息而非普通對象
usage: pbjs [options] file1.proto file2.json ...  (or pipe)  other | pbjs [options] -

文件轉(zhuǎn)換

使用pbjs命令將.proto文件轉(zhuǎn)換為.json文件

#老版本
 ./node_modules/protobufjs/bin/pbjs -t json msg.proto > proto.js
#新版本
 npx pbjs  -t json message.proto --es6 "proto.js"
npx pbjs  -t json message.proto --ts "proto.ts" 

得到的msg.js文件是json格式
在前面加上module.exports =
例如:

module.exports ={
js文件的全部內(nèi)容
  "nested": {
    "com": {
      "nested": {
        "farsunset": {
          "nested": {
            "cim": {
              "nested": 
……………………省略
}

使用pbjs命令將.proto文件轉(zhuǎn)換為.js文件

$ ./node_modules/protobufjs/bin/pbjs -t static_module -w commonjs -o msg.js msg.proto

編寫pbjs命令的轉(zhuǎn)換腳本

$ vim pbjs.cmd

::判斷當(dāng)前目錄是否存在node.exe
@IF EXIST "%~dp0\node.exe" (
    ::使用node執(zhí)行pbjs進行文件轉(zhuǎn)換
    "%~dp0\node.exe" "%~dp0\..\protobufjs\bin\pbjs" %*
) ELSE (
    @SETLOCAL
    ::將環(huán)境變量PATHEXT中的JS刪除
    @SET PATHEXT=%PATHEXT:;.JS;=;%
    ::使用node執(zhí)行pbjs進行文件轉(zhuǎn)換
    node "%~dp0\.. \protobufjs\bin\pbjs" %*
)

使用

由于JavaScript是一種動態(tài)類型語言, protobuf.js引入有效消息的概念鲤遥,以便提供最佳的性能沐寺。

image

不同方法與有效消息之間的關(guān)系

方法 描述
Message.verify(message:Object):null string 驗證普通JavaScript對象是否滿足有效消息的要求,以確保無錯誤的進行加密編碼(encode)盖奈。verify不拋出錯誤而會將錯誤消息作為字符串返回混坞。
Message.encode(message:Message Object [, writer:Writer]):Writer 對消息實例或有效的純JavaScript對象進行編碼,encode不隱式的驗證消息卜朗,而由用戶確定有效負載是有效消息。
Message.encodeDelimited(message:Message Objecct [, writer:Writer]):Writer 將protobuffer解碼為消息實例咕村,如果required字段缺少則會拋出util.ProtocolError錯誤场钉。
Message.decodeDelimited(reader:Reader Uint8Array):Message 工作方式類似于decode函數(shù),會另外讀取一個消息的長度作為變量的預(yù)設(shè)值懈涛。
Message.create(properties:Object):Message 從一組滿足有效消息要求的屬性中創(chuàng)建一個新消息實例逛万,如果適用,建議首選create而非fromObject,因為create不會執(zhí)行可能存在冗余的轉(zhuǎn)換宇植。
Message.fromObject(object:Object):Message 將任何無效的純JavaScript對象轉(zhuǎn)換為消息實例
Message.toObject(message:Message [, options:ConversionOptions]):Object 將消息實例轉(zhuǎn)換為任意純JavaScript對象得封,以便與其它庫或存儲進行互操作。根據(jù)指定的實際轉(zhuǎn)換選項指郁,生成純JavaScript對象忙上。

初始化

$ npm i -g require

let pbroot = require("protobufjs").Root;
let json = require("msg.json");
let root = pbroot.fromJSON(json);

let Message = root.lookupType("ns.Address");

創(chuàng)建

Message.create(properties:Object):Message

從一組滿足有效消息要求的屬性中創(chuàng)建一個新消息實例,如果適用闲坎,建議首選create而非fromObject疫粥,因為create不會執(zhí)行可能存在冗余的轉(zhuǎn)換。

例如;

//數(shù)據(jù)
let data = {province:"", city:"", area:""};
data.province = "hunan";
data.city = "changsha";
data.area = "yuelu";
//創(chuàng)建
let message = Message.create(data);
console.log(message);//Address {province: "hunan", city: "changsha", area: "yuelu"}

驗證

Message.verify(message:Object):null|string

驗證普通JavaScript對象是否滿足有效消息的要求腰懂,以確保無錯誤的進行加密編碼(encode)梗逮。

verify不拋出錯誤而會將錯誤消息作為字符串返回。

let message = Message.create({province:"hunan"});
let errmsg = Message.verify(message);
if(errmsg){
  throw Error(errmsg);
}

序列化編碼

Message.encode(message: Message|Object [, writer: Writer]): Writer

對消息實例或有效的純JavaScript對象進行編碼绣溜,encode不隱式的驗證消息慷彤,而由用戶確定有效負載是有效消息。

let data = {};
data.province= "hunan";
data.city = "changsha";
let buffer= Message.encode(Message.create(data)).finish();

反序列化解碼

Message.decode(reader: Reader|Uint8Array): Message

將protobuffer解碼為消息實例怖喻,如果缺乏required字段則拋出util.ProtocolError錯誤底哗,如果wire格式無效也會拋出錯誤。

//解碼
try{
    let message = Message.decode(buffer);
}catch(e){
    if(e instanceof protobuf.util.ProtocolError){
        //missing required field
    }else{
        //wire format is invalid
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罢防,一起剝皮案震驚了整個濱河市艘虎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咒吐,老刑警劉巖野建,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異恬叹,居然都是意外死亡候生,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門绽昼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唯鸭,“玉大人,你說我怎么就攤上這事硅确∧扛龋” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵菱农,是天一觀的道長缭付。 經(jīng)常有香客問我,道長循未,這世上最難降的妖魔是什么陷猫? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上绣檬,老公的妹妹穿的比我還像新娘足陨。我一直安慰自己,他們只是感情好娇未,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布墨缘。 她就那樣靜靜地躺著,像睡著了一般忘蟹。 火紅的嫁衣襯著肌膚如雪飒房。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天媚值,我揣著相機與錄音狠毯,去河邊找鬼。 笑死褥芒,一個胖子當(dāng)著我的面吹牛嚼松,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锰扶,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼献酗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了坷牛?” 一聲冷哼從身側(cè)響起罕偎,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎京闰,沒想到半個月后颜及,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡蹂楣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年俏站,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痊土。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡肄扎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赁酝,到底是詐尸還是另有隱情犯祠,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布酌呆,位于F島的核電站衡载,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肪笋。R本人自食惡果不足惜月劈,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藤乙。 院中可真熱鬧猜揪,春花似錦、人聲如沸坛梁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽划咐。三九已至拴念,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間褐缠,已是汗流浹背政鼠。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留队魏,地道東北人公般。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像胡桨,于是被迫代替她去往敵國和親官帘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容