安装第三方包
pip install protobuf
pip install grpcio_tools # python的protoc编译器
编写proto文件
helloworld.proto
syntax = "proto3";
package rpc_package;
// 定义服务
service HelloWorldService {
// 定义服务中的方法包括包括请求和返回的参数
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 定义请求参数格式
message HelloRequest {
string name = 1;
}
// 定义返回参数格式
message HelloReply {
string message = 1;
}
编译proto文件
python -m grpc_tools.protoc -I ./ --python_out=./ --grpc_python_out=./ helloworld.proto
# python_out目录指定 xxxx_pb2.py的输出路径,我们指定为./ 当前路径
# grpc_python_out指定xxxx_pb2_grpc.py文件的输出路径,我们指定为./ 当前路径
# grpc_tools.protoc 这是我们的工具包,刚刚安装的
# -I参数指定协议文件的查找目录,我们都将它们设置为当前目录./
# helloworld.proto 我们的协议文件
ls
helloworld_pb2_grpc.py helloworld_pb2.py helloworld.proto
# helloworld.proto 协议文件
# helloworld_pb2.py 里面有消息序列化类
# helloworld_pb2_grpc.py 包含了服务器 Stub 类和客户端 Stub 类,以及待实现的服务 RPC 接口。
服务器文件
hello_server.py
import sys, os
from concurrent import futures
import grpc
import logging
import time
from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server, \
HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
def get_metadata(metadata, key):
#实现一个获取metadata的方法
for data in metadata:
if data.key == key:
return data.value
class Hello(HelloWorldServiceServicer):
# 这里实现我们定义的接口
def SayHello(self, request, context):
print(request.name)
print(get_metadata(context.invocation_metadata(), 'some-md-key'))
return HelloReply(message='Hello, %s!' % request.name)
def serve():
# 这里通过thread pool来并发处理server的任务
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# 将对应的任务处理函数添加到rpc server中
add_HelloWorldServiceServicer_to_server(Hello(), server)
# 这里使用的非安全接口,实际上gRPC支持TLS/SSL安全连接,以及各种鉴权机制
server.add_insecure_port('[::]:50000')
server.start()
print("server start ok ")
try:
while True:
time.sleep(60 * 60 * 24)
except KeyboardInterrupt:
server.stop(0)
if __name__ == "__main__":
logging.basicConfig()
serve()
客户端文件
hello_client.py
from __future__ import print_function
import logging
import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub
def run():
# 使用with语法保证channel自动close
with grpc.insecure_channel('localhost:50000') as channel:
# 客户端通过stub来实现rpc通信
stub = HelloWorldServiceStub(channel)
metadata = (('md-key', 'csdn'),('some-md-key', 'another value'))
# 客户端必须使用定义好的类型,这里是HelloRequest类型
response = stub.SayHello(HelloRequest(name='python'), metadata = metadata)
print ("hello client received: " + response.message)
if __name__ == "__main__":
logging.basicConfig()
run()
运行
先运行hello_server.py
再运行hello_client.py
内容参考于:https://blog.youkuaiyun.com/qq_30966497/article/details/107025861