1.编写proto文件:data.proto
syntax = "proto3";
//package example;
service FormatData { //定义服务,用在rpc传输中
rpc DoFormat(actionrequest) returns (actionresponse){}
}
message actionrequest {
string text = 1;
}
message actionresponse{
string text=1;
}
2.运行
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./data.proto
生成文件:data_pb2_grpc.py 和data_pb2.py
3.编写客户端代码:server.py
# 实现了 server 端用于接收客户端发送的数据,并对数据进行大写处理后返回给客户端
# ! /usr/bin/env python
# -*- coding: utf-8 -*-
# import grpc
# import time
# from concurrent import futures
# import data_pb2, data_pb2_grpc
#
# _ONE_DAY_IN_SECONDS = 60 * 60 * 24
# #localhost
# _HOST = 'localhost'
#
# # _HOST = '192.168.2.107'
# _PORT = '8080'
#
# # 实现一个派生类,重写rpc中的接口函数.自动生成的grpc文件中比proto中的服务名称多了一个Servicer
# class FormatData(data_pb2_grpc.FormatDataServicer):
# # 重写接口函数.输入和输出都是proto中定义的Data类型
# def DoFormat(self, request, context):
# str = request.text
# print(data_pb2.actionresponse(text=str.upper()))
# img = base64.b64decode(str)
# return data_pb2.actionresponse(text=str.upper()) # 返回一个类实例
#
#
# def serve():
# # 定义服务器并设置最大连接数,corcurrent.futures是一个并发库,类似于线程池的概念
# grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4)) # 创建一个服务器
# data_pb2_grpc.add_FormatDataServicer_to_server(FormatData(), grpcServer) # 在服务器中添加派生的接口服务(自己实现了处理函数)
# grpcServer.add_insecure_port(_HOST + ':' + _PORT) # 添加监听端口
# grpcServer.start() # 启动服务器
# try:
# while True:
# print('start===============>')
# time.sleep(_ONE_DAY_IN_SECONDS)
# except KeyboardInterrupt:
# grpcServer.stop(0) # 关闭服务器
import grpc
import time
from concurrent import futures
import data_pb2, data_pb2_grpc
import cv2
import base64
import numpy as np
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
#localhost
_HOST = 'localhost'
# _HOST = '192.168.2.107'
_PORT = '8080'
# 实现一个派生类,重写rpc中的接口函数.自动生成的grpc文件中比proto中的服务名称多了一个Servicer
class FormatData(data_pb2_grpc.FormatDataServicer):
# 重写接口函数.输入和输出都是proto中定义的Data类型
def DoFormat(self, request, context):
str = request.text
print(data_pb2.actionresponse(text=str.upper()))
decode_img = base64.b64decode(str)
img = np.fromstring(decode_img,dtype=np.int8)
img = np.reshape(img,(480,640,3))
# img2 = cv2.imdecode(img)
# cv2.imshow('opencv',img2)
# img = np.ndarray(img,np.int8)
cv2.imshow('img',img)
cv2.waitKey(100)
return data_pb2.actionresponse(text='xgs') # 返回一个类实例
def serve():
# 定义服务器并设置最大连接数,corcurrent.futures是一个并发库,类似于线程池的概念
grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4)) # 创建一个服务器
data_pb2_grpc.add_FormatDataServicer_to_server(FormatData(), grpcServer) # 在服务器中添加派生的接口服务(自己实现了处理函数)
grpcServer.add_insecure_port(_HOST + ':' + _PORT) # 添加监听端口
grpcServer.start() # 启动服务器
try:
while True:
print('start===============>')
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
grpcServer.stop(0) # 关闭服务器
if __name__ == '__main__':
serve()
4.编写客户点代码:client.py
# -*- coding: utf-8 -*-
#================================================================
# Copyright (C) 2020 * Ltd. All rights reserved.
# Time : 2020/3/27 22:08
# Author : Xuguosheng
# File : client.py
# Software: PyCharm
# Description :
#================================================================
# 实现了客户端用于发送数据并打印接收到 server 端处理后的数据
# ! /usr/bin/env python
# -*- coding: utf-8 -*-
# import grpc
# import data_pb2, data_pb2_grpc
#
# _HOST = 'localhost'
# _PORT = '8080'
# # class FormatData(data_pb2_grpc.FormatDataServicer):
# # # 重写接口函数.输入和输出都是proto中定义的Data类型
# # def DoFormat(self, request, context):
# # str = request.text
# # return data_pb2.actionresponse(text=str.upper()) # 返回一个类实例
#
# def run():
# conn = grpc.insecure_channel(_HOST + ':' + _PORT) # 监听频道
# print(conn)
# client = data_pb2_grpc.FormatDataStub(channel=conn) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接
# print(client)
# for i in range(5):
#
# response = client.DoFormat(data_pb2.actionrequest(text='hello,world!')) # 返回的结果就是proto中定义的类
# print("received: " + response.text)
#
#
# if __name__ == '__main__':
# run()
import grpc
import data_pb2, data_pb2_grpc
import cv2
import base64
import numpy as np
_HOST = 'localhost'
_PORT = '8080'
# class FormatData(data_pb2_grpc.FormatDataServicer):
# # 重写接口函数.输入和输出都是proto中定义的Data类型
# def DoFormat(self, request, context):
# str = request.text
# return data_pb2.actionresponse(text=str.upper()) # 返回一个类实例
def run():
conn = grpc.insecure_channel(_HOST + ':' + _PORT) # 监听频道
print(conn)
client = data_pb2_grpc.FormatDataStub(channel=conn) # 客户端使用Stub类发送请求,参数为频道,为了绑定链接
print(client)
cap = cv2.VideoCapture(0)
while True:
ret,frame = cap.read()
print(frame.shape)
cv2.waitKey(100)
# frame_string = frame.tostring()
# str = cv2.imencode('.jpg',frame)[1]
str = base64.b64encode(frame)
# img = base64.b64decode(str)
# print(type(img))
# with open("tr2image.png", 'wb') as str2image:
# str2image.write(str.decode('base64'))
# str = frame.tostring()
cv2.imshow('oo',frame)
response = client.DoFormat(data_pb2.actionrequest(text=str)) # 返回的结果就是proto中定义的类
print("received: " + response.text)
if __name__ == '__main__':
run()
5.运行便可以从客户端传图到服务端