一、客户端给服务器传数据
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.valuesprint(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())