grpc服务器和客户端互传数据

一、客户端给服务器传数据

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())

猜你喜欢

转载自blog.csdn.net/weixin_38383877/article/details/87879360