🔲

ProtocolBuffersのencodeとdecodeの方法

2024/08/23に公開

下準備

今回使うprotoファイルを作成する

syntax = "proto3";
package main;

service PingPongService {
  rpc Ping(PingRequest) returns (PingResponse);
}
message PingRequest {
  string message = 1;
}
message PingResponse {
  string message = 1;
}

簡単コピペ用に下記ヒアドキュメントを置いておきます。

cat <<\EOF> main.proto
ここに上記のprotoファイルの中身をコピペする
EOF 

今回使うprotoのテキストデータファイルを作成する

cat <<\EOF> hoge.txt 
message: "aaa"
EOF

作業開始

【encode】テキストデータファイルをprotobuffのバイナリ形式に変換する

cat hoge.txt | protoc --encode=main.PingRequest main.proto > hoge.bin

【decode】protobuffのバイナリ形式をテキストデータファイルに変換する

cat hoge.bin | protoc --decode=main.PingRequest main.proto

おまけ

バイナリにgRPC-WEB用の先頭識別子を追加する

printf '\x00\x00\x00\x00\x05' | cat - hoge.bin > hoge_added.bin

curlでgRPC-WEBサーバにリクエストする

cat hoge_added.bin \
     | curl -v 'http://127.0.0.1:50051/main.PingPongService/Ping' \
      -H 'content-type: application/grpc-web+proto' \
      --data-binary '@-' \
      --output -

追加した先頭識別子(5byteのデータ)をカットする(バイナリを元に戻す)

dd if=hoge_added.bin bs=1 skip=5 of=hoge_cut.bin

おまけ2

FireFoxブラウザからgRPC-WEBでクライアントリクエストすると、ネットワークタブから対象のリクエストを選択 - 右クリック - Curlでコピーすると、一気にバイナリのテキスト表現が得られる。

バイナリのテキスト表現を使って下記のコマンドを打てば保存できる。

printf '\x00\x00\x00\x00\x05...' > firefox_added.bin

なぜか、Chromeだと上記のバイナリテキスト表現ではないので、コピペできない。。。
(そもそも、どちらのブラウザもcurlでコピーして動かないのをどうにかしてほしいが。。。)

最後に

gRPC周りで何かあるとバイナリでのやりとりで調査が面倒であると思う。

とりあえず、エンコード・デコードの方法が分かったので何かあったときに使えればと思う。

参考記事

https://medium.com/@nathantnorth/protocol-buffers-text-format-14e0584f70a5

https://qiita.com/nozmiz/items/5f56b5e8e280c22121de

Discussion