以Python做Server,Golang做Client为例。
.proto:
syntax = "proto3"
package PACKAGE_NAME
message Message1 {
int32 data_1 = 1;
string data_2 = 2;
...//More about data type, read https://developers.google.com/protocol-buffers/docs/proto3#scalar
}
message Message2 {
int32 data_3 = 1;
repeated string data_4 = 2; //Use 'repeated [DATA_TYPE]' to sub array;
}
service Service1 {
rpc SomeFunc(Message1) returns (Message2) {}
}
Python as server:
pip install grpcio-tools
python3 -m grpc_tools.protoc -I PACKAGE_NAME --python_out=[SOME_DIR] --grpc_python_out=[SOME_DIR] ./XXX.proto
对应目录下会生成名为*_pb2.py和*_pb2_grpc.py的两个py文件。
server.py
import grpc
from multiprocessing import Pool
from concurrent import futures
import XXX_pb2_grpc, XXX_pb2
class Service1Servicer(XXX_pb2_grpc.Service1Servicer):
def SomeFunc(self, request, context):
# 可通过__getattr__从request取出proto中Message1定义的各项
response = XXX_pb2.Message2()
reponse.data_3 = ...
response.data_4.append(...)
return response
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
XXX_pb2_grpc.add_Sevice1Servicer_to_server(Service1Servicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("grpc server has already started.")
try:
while True:
time.sleep(9999999)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
Golang as client:
go get -u github.com/golang/protobuf/protoc-gen-go
protoc --go_out=plugins=grpc:. ./XXX.proto
目录下会生成一个xxx.pb.go
client.go
package main
import (
xxx // 刚生成的go文件
"google.golang.org/grpc"
"context"
"fmt"
"time"
)
func main() {
conn, err := grpc.Dial(":50051", grpc.WithInsecure())
if err != nil {
fmt.Println(err)
}
client := xxx.NewService1Client(conn)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
response, err := client.SomeFunc(ctx, &xxx.Message1{data_1: xxx, data_2:xxx, ...})
if err != nil {
fmt.Println(err)
} else {
fmt.Println(response.Message2)
}
}