概要
gRPC はハイパフォーマンスな RPC フレームワークです
Protocol Buffers と呼ばれるインタフェース言語を使って呼び出し元の関数などを定義することができます
今回は Ruby でサンプルのコードを動かしてみました
環境
- macOS 10.14.5
- Ruby 2.6.2p47
- grpc 1.21.0
準備
公式からサンプルが提供されているのでそれを元に動かしてみます
git clone https://github.com/grpc/grpc
cd grpc/examples/ruby/
bundle install --path vendor
'bundler', '~> 1.7'
になっているので bundler のバージョンが新しい場合はバージョンの部分を削除してください
bundle exec ruby greeter_server.rb
でサーバを起動しておきましょう
bundle exec ruby greeter_client.rb
別ターミナルでクライアントを起動して "Greeting: Hello world"
が返ってくれば OK です
今回のチュートリアルではこれらのサーバーとクライアントコードを修正します
helloworld.proto ファイルの修正
まず proto
ファイルを修正します
proto
ファイルには RPC で呼び出されるメソッドの引数と返り値を定義してあります
vim ../protos/helloworld.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
コメントの部分は削除しています
いろいろと書いていますが 1 行追記しているだけです
追記した箇所は rpc SayHelloAgain
の行になります
message
を使って引数と返り値のデータを定義することができます
あとはそれらを使った service
を定義すれば OK です
grpc-tools のインストール
作成した proto ファイルからコードを生成してくれるツールです
コマンドとして使うのでグローバルにインストールしましょう
gem install grpc-tools
コード生成
では proto ファイルからコードを生成します
実行しているパスは examples/ruby
になります
grpc_tools_ruby_protoc -I ../protos --ruby_out=lib --grpc_out=lib ../protos/helloworld.proto
(Mac で実行して PATH が通っていない場合は /usr/local/lib/ruby/gems/2.6.0/bin/grpc_tools_ruby_protoc
あたりを探してみてください)
-I
が proto ファイルを検索するディレクトリを指定します
--ruby_out
と --grpc_out
は生成されるコードを配置するディレクトリを指定します
あとは生成元の proto ファイルのパスを指定すれば OK です
成功すると lib ディレクトリ配下の helloworld_pb.rb
と helloworld_services_pb.rb
が新たに生成されています
サーバコードを修正する
新たに追加したメソッドをサーバ側で使ってみます
vim greeter_server.rb
this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(this_dir, 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc'
require 'helloworld_services_pb'
class GreeterServer < Helloworld::Greeter::Service
def say_hello(hello_req, _unused_call)
Helloworld::HelloReply.new(message: "Hello #{hello_req.name}")
end
def say_hello_again(hello_req, _unused_call)
Helloworld::HelloReply.new(message: "Hello again, #{hello_req.name}")
end
end
def main
s = GRPC::RpcServer.new
s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
s.handle(GreeterServer)
s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT'])
end
main
コメントの部分は削除しています
追記したのは def say_hello_again
メソッドになります
say_hello_again
は proto ファイルで定義した rpc SayHelloAgain
をスネークケースに変換した名前にしましょう
クライアントコード修正
追加したメソッドをクライアントコードで呼ぶようにしましょう
vim greeter_client.rb
this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(this_dir, 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc'
require 'helloworld_services_pb'
def main
stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
user = ARGV.size > 0 ? ARGV[0] : 'world'
message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message
p "Greeting: #{message}"
message = stub.say_hello_again(Helloworld::HelloRequest.new(name: user)).message
p "Greeting: #{message}"
end
main
コメントは削除しています
main
内の最後の 2 行を追加しています
要するに追加した say_hello_again
メソッドをコールしているだけです
動作確認
bundle exec ruby greeter_server.rb
でサーバを起動しましょう
bundle exec ruby greeter_client.rb
でクライアントを実行し "Greeting: Hello again, world"
も新たにレスポンスに追加されれば OK です
grpcurl
クライアント側は grpcurl
というコマンドでも確認することができます
brew install grpcurl
grpcurl -plaintext -d '{"name":"world"}' -proto ../protos/helloworld.proto -import-path ../protos/ localhost:50051 helloworld.Greeter/SayHello
=> { "message": "Hello world" }
こんな感じです
また定義されているサービスの一覧なども確認できます
grpcurl -plaintext -proto ../protos/helloworld.proto -import-path ../protos/ localhost:50051 list
=> helloworld.Greeter
grpcurl -plaintext -proto ../protos/helloworld.proto -import-path ../protos/ localhost:50051 describe helloworld.Greeter
でコール可能なメソッド定義の一覧を取得できます
最後に
Ruby で gRPC に入門してみました
今回は公式のサンプルとクイックスタートを元に動かしてみただけなので詳しい機能などには触れていません
流れとして
- proto ファイルにメソッドを定義
grpc_tools
で Ruby のコードを生成- server ファイルでメソッドを実装
しているということが理解できれば OK かなと思います
基本的には生成されたコードには触れずサーバとクライアントコードを変更していく感じなります
0 件のコメント:
コメントを投稿