1、data.proto
syntax = 'proto3'; // 服务定义 service data{ // 函数定义 data_request参数 data_reply返回数据 rpc serving(data_request) returns (data_reply) {} } message data_request{ string cmd= 1; } message data_reply{ string values = 1; }
2、data_client.py
import data_pb2 import data_pb2_grpc import grpc import base64 import time def run(): # 监听频道 channel = grpc.insecure_channel('127.0.0.1:8080') # 客户端使用Stub类发送请求, 参数为频道, 为了绑定链接 stub = data_pb2_grpc.dataStub(channel) while True: # 返回的结果就是proto中定义的类 f = open("data.json", 'rb') img_64 = base64.b64encode(f.read()) f.close() response = stub.serving(data_pb2.data_request(cmd=img_64)) print(response) value = response.values print(value) time.sleep(10) if __name__ == '__main__': run()
3、data_server.py
import data_pb2 import data_pb2_grpc import grpc from concurrent import futures import time import base64 class ServerGreeter(data_pb2_grpc.dataServicer): # 重写接口函数.输入和输出都是proto中定义的Data类型 def serving(self, request): img_64 = base64.b64decode(request.cmd) if img_64: f = open('datacopy.json', 'wb') f.write(img_64) f.close() return data_pb2.data_reply(values="ok") def serve(): # 定义服务器并设置最大连接数,corcurrent.futures是一个并发库,类似于线程池的概念 # 创建一个服务器 server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) # 在服务器中添加派生的接口服务(自己实现了处理函数) a=data_pb2_grpc.add_dataServicer_to_server(ServerGreeter(), server) # 添加监听端口 server.add_insecure_port('127.0.0.1:8080') #启动服务 server.start() try: while True: time.sleep(1) except KeyboardInterrupt: server.stop(0) if __name__ == '__main__': serve()
1、data.proto
syntax = 'proto3'; // 服务定义 service data{ // 函数定义 data_request参数 data_reply返回数据 rpc serving(data_request) returns (data_reply) {} } message data_request{ string cmd= 1; } message data_reply{ string values = 1; }
2、client.py
import data_pb2 import data_pb2_grpc import grpc import base64 _HOST='localhost' _PORT='8080' def run(): channel = grpc.insecure_channel(_HOST+':'+_PORT) stub = data_pb2_grpc.dataStub(channel) response = stub.serving(data_pb2.data_request()) imgf = base64.b64decode(response.values) f = open('./b.jpg', 'wb') f.write(imgf) f.close() if __name__ == '__main__': run()
3、server.py
import data_pb2 import data_pb2_grpc import grpc from concurrent import futures import time import base64 _HOST='localhost' _PORT='8080' class ServerGreeter(data_pb2_grpc.dataServicer): def serving(self, request, context): print('serving:', request.cmd) f = open('./a.jpg', 'rb') img_64 = base64.b64encode(f.read()) f.close() return data_pb2.data_reply(values=img_64) def serve(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) data_pb2_grpc.add_dataServicer_to_server(ServerGreeter(), server) server.add_insecure_port(_HOST+':'+_PORT) server.start() try: while True: time.sleep(60 * 60 * 24) except KeyboardInterrupt: server.stop(0) if __name__ == '__main__': serve()
若是服务器往客户端发送消息,就利用在服务器中重写类的方法的return中。形式为data.proto中的data_reply中定义的value=XXX。如data_pb2.data_reply(values=img_64)
若是服务器接收客户端发送的消息,就利用在服务器中重写类的方法中的参数request。形式为data.proto中的data_request中定义的cmd。如img_64 = base64.b64decode(request.cmd)
若是客户端给服务器发送消息,就利用stub存根的方法此时需要使用data_request中定义的cmd,如response = stub.serving(data_pb2.data_request(cmd=img_64))
若是客户端接收服务器发送过来的消息,就直接利用stub存根的方法。response = stub.serving(data_pb2.data_request())