gRpc入门步骤详解
1. 安装Go 1.16、Python 3
brew install go@1.16
brew install python3
2. 环境变量和其他配置
# pip mirror
mkdir -p ~/.pip
cat >~/.pip/pip.conf <<EOF
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
EOF
# go path
export GOPATH=/Users/apple/go
export PATH=$PATH:$GOPATH/bin
3. 安装依赖库
# go grpc gen
go get -u github.com/golang/protobuf/protoc-gen-go
# python grpc gen
pip3 install grpcio
pip3 install protobuf
pip3 install grpcio_tools
4. 准备工程目录结构
# prepare project directory
mkdir -p grpc-demo
cd grpc-demo
go mod init grpc-demo
# prepare proto-buf directory
mkdir -p pb
# prepare server directory
mkdir -p server
#prepare client directory
mkdir -p client
#prepare service directory
mkdir -p service
5. 定义.proto协议文件及生成Go代码
# file pb/hello_grpc.proto
syntax = "proto3";
package service;
option go_package = ".;service";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
生成Go版本的协议代码
protoc -I pb/ pb/hello_grpc.proto --go_out=plugins=grpc:service
-I
后面指定proto文件存放目录,和proto文件
--go_out=plugins=grpc:
后面指定生成go代码存放的目录
检查文件service/hello_grpc.pb.go
是否成功生成
6. 编写Go Server代码及运行Server
# file server/server.go
package main
import (
"context"
"fmt"
"hello_grpc/service"
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
type server struct{}
func (s *server) SayHello(ctx context.Context, in *service.HelloRequest) (*service.HelloReply, error) {
return &service.HelloReply{Message: "hello " + in.Name}, nil
}
type GreeterServer interface {
SayHello(context.Context, *service.HelloRequest) (*service.HelloReply, error)
}
func main() {
// listen local port
lis, err := net.Listen("tcp", ":5000")
if err != nil {
fmt.Printf("fail to listen: %s", err)
return
}
// create grpc server
s := grpc.NewServer()
// register function
service.RegisterGreeterServer(s, &server{})
reflection.Register(s)
err = s.Serve(lis)
if err != nil {
fmt.Printf("fail to start server: %s", err)
return
}
}
运行Server,若发现报错则于项目根目录先执行go mod tidy
准备好依赖。
go run server/server.go
7. 编写Go Client代码及测试Client
# file client/client.go
package main
import (
"context"
"fmt"
"hello_grpc/service"
"google.golang.org/grpc"
)
func main() {
// connect server
conn, err := grpc.Dial(":5000", grpc.WithInsecure())
if err != nil {
fmt.Printf("fail to connect server: %s", err)
return
}
defer conn.Close()
// create new client
c := service.NewGreeterClient(conn)
// call rpc function
r, err := c.SayHello(context.Background(), &service.HelloRequest{Name: "grpc"})
if err != nil {
fmt.Printf("fail to call rpc function: %s", err)
return
}
fmt.Printf("rpc call success: %s", r.Message)
}
运行Client测试
% go run client/client.go
rpc call success: hello grpc
8. 编写Python Client并测试Client
第一步,生成Python语言协议文件hello_grpc_pb2.py
和hello_grpc_pb2_grpc.py
mkdir -p python
python3 -m grpc_tools.protoc -I pb/ --python_out=python/ --grpc_python_out=python/ pb/hello_grpc.proto
第二步,编写Python Client
# file python/client.py
import logging
import grpc
import hello_grpc_pb2
import hello_grpc_pb2_grpc
def run():
with grpc.insecure_channel('localhost:5000') as channel:
stub = hello_grpc_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(hello_grpc_pb2.HelloRequest(name='grpc'))
print("call success: {}!".format(response.message))
if __name__ == '__main__':
logging.basicConfig()
run()
第三步,运行Python Client
% python3 python/client.py
call success: hello grpc!