JavaでProtocol Buffer使ってくれと頼まれた話

まあ使ってくれと言われたというか、ここのWebSocketつなげて、って頼まれたからサイト見てみたら、なんか知らない形式のメッセージ送信しないといけなかったという話

 

サンプルコードをもらったわけですが、中身見てもかなり意味不明

マジこれどうなってんの?ってことで、ソースだけ見てもさっぱりだから調べてみることに

WebSocketでの接続に関してはサンプルソース貰ったから、とりあえずメッセージの送信だけどうするんだよ、というのを調べてみました

 

参考サイト

qiita.com

とりあえずProtocol Bufferとは何ぞやって感じの話しなんですが、この形式に添ってデータ送ってくれたら言語関係なくこの形式で帰ってくるよ

みたいな感じの規格っぽい?

 

で、その規格というか項目が接続先のリファレンス的なページで公開されてたので、なるほどこの項目を送信すればいいんだな!

……で? どうやって?

という話に

 

サンプル見る限り、送信用のクラスは何が書かれてるのかさっぱりなレベルで意味不明

こんなもんコピーしても作れねえよ……って感じだったんですが 

message Sample {
  required int64 sample1 = 1;
  optional Result sample2 = 2;
  required string sample3 = 3;
}

こんな感じでメッセージ送ってね、みたいな項目があったら

それをテキストに保存して拡張子をprotoに保存した後

 

github.com

Gitからクラスファイルを作ってくれるexeを落としてくることに

今回はwindowsだったのでprotoc-3.11.1-win64.zipを落としてきました

 

展開すると中にbinフォルダとincludeフォルダがあるんですが、exeはbinフォルダの方に

これでexeをたたけばオッケー!

なんてこともなく、コマンドラインでたたく必要があるんですが

 

今回はJava用のクラスが欲しかったので、コマンドプロンプトでbinフォルダまで移動した後に、以下のコマンドを入力


protoc --java_out=. test.proto

java_outの後ろが出力先のフォルダ

test.protoは読み込むファイル名

で行けるはず

 

これを実行するとクラスファイルができる!

……と、いいんですが、なんか実際にやってみるとエラーが

 ちょっと調べた結果、protoファイルに追加をすることに


syntax = "proto2";

import "google/protobuf/descriptor.proto";
import "test2.proto";

option java_package = "test.proto";
option java_outer_classname = "Test";
    
message Sample {
  required int64 sample1 = 1;
  optional Result sample2 = 2;
  required string sample3 = 3;
}

 

追加したのはsyntaxからjava_outer_classnameまで奈わけですが

下二つは単純にパッケージとかクラス名をそれにしてくれるって言うだけ

syntaxはよくわからないんですがコンパイルバージョン?的なのっポイ

proto3があるみたいですが、今回の接続先のメッセージ見てたらproto2じゃないとエラーが出たのでとりあえずproto2に

 

で、一番困ったのがimportの部分

test2.protoはこれ単純にtest.protoファイルで使ってるクラスはこっちで定義してますよって感じで、普通にソースコード書くときにインポートするのと同じような感じで書いたわけですが……その上のインポート

これ、サンプルで渡されたprotoファイルに書かれてたからとりあえずつけてみたんですが、こんなファイルねえよ!って怒られることに

まあないから当たり前なんですが、じゃあどこにあるんだよ!となったわけですね

まあ結論から言うと展開したファイルのincludeフォルダの中に入ってたので、include/googleフォルダをコピーしてexeのあるフォルダに配置した無事クラスファイルが出力されることになりました

 

中身見ても何がいてあんのかさっぱりわかんね

な、感じですが、とりあえずサンプルソースと同じような関数呼び出せばデータ送信できることはわかったのでまあいいや……ということに

 

で、わざわざこれを記事というか備忘録にしたのはもちろん

Protoファイルからクラスファイルを作る手順絶対忘れる!

 ってことですね……

これから定期的にメッセージの送信する羽目になった時にこれ忘れると毎度探しに行かないといけないので、メモ代わりに

 

ちなみに先にC#で繋げない?って言われてC#の方を調べてそっちでもクラスファイルを作ったわけですが……まさか今回もう一回使うことになるとは全く思ってなかったのでC#の方はメモしてないっていうね……後悔先に立たずですわ……