步骤:
1、装依赖
pip install grpcio
pip install protobuf
pip install grpcio-tools
2、写proto
//demo.proto
syntax = "proto3";
package demo;
service Demo {
rpc demo_func (demo_request) returns (demo_reply) {}
}
message demo_request {
string name = 1;
int32 age = 2;
}
message demo_reply {
string message = 1;
int32 salary = 2;
}
3、生成通信用的代码
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. demo.proto
4、写server、client
server
# coding=utf-8
# demo_server.py
import time
from concurrent import futures
from demo_pb2 import *
from demo_pb2_grpc import *
class MyDemo(DemoServicer):
def __init__(self):
pass
def demo_func(self, request, context):
print("request name:{0}, age:{1}".format(request.name, request.age))
return demo_reply(message=request.name, salary=10000)
def serve(port=50051):
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_DemoServicer_to_server(MyDemo(), server)
server.add_insecure_port(f'[::]:{port}')
server.start()
try:
while True:
time.sleep(3)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve(50051)
client
# coding=utf-8
# demo_client.py
from __future__ import print_function
from demo_pb2 import *
from demo_pb2_grpc import *
def run(host, port):
channel = grpc.insecure_channel(f'{host}:{port}')
stub = DemoStub(channel)
response = stub.demo_func(demo_request(name='tom', age=32))
print("message: {0}: salary:{1}".format(response.message, response.salary))
if __name__ == '__main__':
run(host='localhost', port=50051)
客户端发:
request name:tom, age:32
服务端回复:
message: tom: salary:10000
解释:
1、demo.proto:
定义协议版本proto3
; 取一个包名字demo
, 给服务取一个名字,比如Demo
, 该协议有一个函数,名叫demo_func
, 该函数的输入参数是一个叫demo_request
的结构体,结构体里面有string类型的name
和int类型的age
; 然后函数返回值是一个结构体demo_reply
包含string 类型的message
和int类型的salary
。这些结构体都可以通过 .
访问成员变量。
2、代码生成:
简单讲就是使用grpc_tools.protoc
工具,根据定义的demo.proto
生成对应的通信文件 demo_pb2.py
demo_pb2_grpc.py
3、server端:
定义一个类MyDemo
,该类继承了我们协议生成的类DemoServicer
,可以看见协议生成的类的名字就是服务名字Demo
加Servicer
, 复写函数demo_func
, demo_func
的输入是结构体request
(含有name
age
)以及通信需要的 context
。返回的是结构体demo_reply
(包含成员message
salary
) 。server()
就是用线程池的方式启动服务,先添加服务,设置监听端口50051
,然后启动服务。
4、client端:
定义一个channel
, 设置需要连接的server
的ip
和port
; 然后将channel
传给DemoStub
,可以看出为服务名字Demo
+ Stub
。然后stub就可以调用函数demo_func
函数参数为结构体demo_request
(包含name
和age
)。response
就是回复的结构体,包含message
和salary
直接.
访问成员变量。
GRPC可以实现进程间通信,也可以实现跨机器进程间通信。