7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

tomowarkar ひとりAdvent Calendar 2019

Day 24

goとpythonで始めるgRPCの事始め

Last updated at Posted at 2019-10-31

gRPCってなんだって思って調べてたら実装してしまっていたので備忘録として残します。

ゴール

このようなディレクトリ構造でpythonクライアントとgoサーバー間でgRPCを実装していくことをゴールとします.

$GOPATH/src/pygo-grpc/
  ├ client/
  | ├ app.py
  | ├ hello_pb2_grpc.py     (gRPC自動生成)
  | └ hello_pb2.py        (gRPC自動生成)
  ├ protos/
  | └ hello.protc
  └ server/
    ├ grpc-server/hello.pb.go (gRPC自動生成)
    └ server.go

プロトコルを定義

  • $GOPATHの配下に新しいワーキングディレクトリを作成し、プロトコルを定義します。
~ $ cd $GOPATH/src
src $ mkdir pygo-grpc;cd $_
pygo-grpc $ mkdir client protocs server server/grpc-server
pygo-grpc $ touch protocs/hello.proto
protocs/hello.proto

syntax = "proto3";

package hello;

service Hello {
  rpc PushMsg (MsgStruct) returns (MsgStruct) {}
}

message MsgStruct {
  string message = 1;
}

パラメータ、戻り値、呼び出しメソッドを定義しています。
今回は簡単なメッセージの通信を実装するので、PushMsgというメソッドを定義し、そのパラメータと戻り値をどちらも同じMsgStructで定義します。

GoでgRPCサーバーを実装する

GoのgRPC周りのインストール

まだの人はチャチャッとやってしまいましょう。

go version // 1.6以上必要
go get -u google.golang.org/grpc // Install gRPC
go get -u github.com/golang/protobuf/protoc-gen-go // Install the protoc plugin

GoのgRPCコードを生成

protoファイルの場所とgRPCコードを生成する場所を指定。

pygo-grpc $ protoc -I protocs/ protocs/hello.proto --go_out=plugins=grpc:server/grpc-server/

server/grpc-server/hello.pb.goが自動生成されます。

GoのgRPCサーバー実装

pygo-grpc $ touch server/server.go
server/server.go
package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	pb "pygo-grpc/server/grpc-server"
)

const (
	port = ":50051"
)

type server struct {
	pb.UnimplementedHelloServer
}

func (s *server) PushMsg(ctx context.Context, p *pb.MsgStruct) (*pb.MsgStruct, error) {
	log.Printf("Received: %v", p.Message)
	return &pb.MsgStruct{Message: "Hello " + p.Message}, nil
}

func main() {
	lis, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	pb.RegisterHelloServer(s, &server{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

PythonでgRPCクライアントを実装する

pythonの仮想環境の立ち上げ

pygo-grpc $ virtualenv venv && source venv/bin/activate

venvはトレースしなくて大丈夫なので .gitignoreにでも

PythonのgRPC周りのインストール

(venv) pygo-grpc $ pip install grpcio
(venv) pygo-grpc $ pip install grpcio-tools

PythonのgRPCコードを生成

(venv) pygo-grpc $ python -m grpc_tools.protoc -I protocs --python_out=client --grpc_python_out=client protocs/hello.proto

client/hello_pb2_grpc.pyclient/hello_pb2.py が自動生成されます

PythonのgRPCクラアイアント実装

client/app.py
from __future__ import print_function
import logging

import grpc

import hello_pb2
import hello_pb2_grpc


def run():
  msg = input()
  with grpc.insecure_channel('localhost:50051') as channel:
      stub = hello_pb2_grpc.HelloStub(channel)
      stub.PushMsg(hello_pb2.MsgStruct(message=msg))

if __name__ == '__main__':
    logging.basicConfig()
    run()

動作確認

まずサーバーを立ち上げ

pygo-grpc $ go run server/server.go

次にクライアントを立ち上げます

(venv) pygo-grpc $ python client/app.py

画面収録 2019-10-31 19.15.00.gif

うまくいきました😆

written by tomowarkar

参考

https://grpc.io/docs/quickstart/go/
https://grpc.io/docs/quickstart/python/

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?