GolangでgRPCのStreamを試してみる
その次のこのStreamがあるという流れです。
ソースはここ
やりたいこと
チャットサーバとクライアントみたいなのを作ってみるよ!!!
機能
クライアントからサーバにメッセージを送る
サーバからクライアントにメッセージを送る
たったこれだけ。
これをprotocに書くとこんな感じ。
code:protoc
service Messenger {
// メッセージ送信
rpc Send (Message) returns (SendResult) {}
// メッセージ受信ストリーム
rpc Receive (ReceiveRequest) returns (stream Message) {}
}
主語はクライアントになるように作ってみてる。
サーバサイド
チャットサーバってことは、いろんなクラインとからのメッセージをとりあえず各クライアントに返すってだけですわ。
ってことは、Receiveが来たところで、そのstreamをどこかに保持しておくことにします。
あとはstreamが切れないようにするだけ。
code:golang
func (s *server) Receive(_ *pb.ReceiveRequest, stream pb.Messenger_ReceiveServer) error {
s.mutex.Lock()
s.num++
s.mutex.Unlock()
ch := make(chan bool)
<-ch
return nil
}
上書きしたらつらいので一応排他制御してる。
メッセージを受信したら、それまでに開かれたstreamに受けたメッセージをなげるだけ。
code:golang
func (s *server) Send(_ context.Context, message *pb.Message) (*pb.SendResult, error) {
for k, stream := range s.streams {
err := stream.Send(message)
if err != nil {
log.Println(err)
delete(s.streams, k)
}
}
return &pb.SendResult{Result: true}, nil
}
サーバがやってることはめっちゃ単純!!!
受けたらそれまで開いたところに流す。たったそれだけ!!!
クライアントサイド
何にも複雑なことをしてないのでソースまるまる見てもらったほうが早いかも。
goで非同期にメッセージ受信。
あとは標準入力を送信し続けるだけ。
単純☆
おわりに
簡単すぎて書くことがない。
それくらいgRPCとpbによって抽象化されていて、苦しむことがない。
更新日時: 2019/05/29