Python+grpc

本文详细介绍了如何使用gRPC和protobuf进行服务端和客户端的搭建,包括protobuf的数据类型映射、四种RPC模式的解释,以及Python中gRPC服务器和客户端的实现代码。此外,还提供了调整消息传输阈值的方法,以适应大文件传输需求。
摘要由CSDN通过智能技术生成

Grpc Demo

grpc包

pip install grpcio #gRPC 的安装 
pip install protobuf  #ProtoBuf 相关的 python 依赖库
pip install grpcio-tools   #python grpc 的 protobuf 编译工具

protobuf

grpc是基于protobuf来进行数据传输的 
分为四种传输方式
	1. 一元RPC模式 
	2. 响应流式 RPC 
	3. 请求流式 RPC 
	4. 双向流式 RPC

protobuf 对应 python的数据格式

protobufpython
doublefloat
floatfloat
int32int
int64int/long
uint32int/long
uint64int/long
sint32(可用于负数)int
sint64(可用于负数)int/long
boolbool
string(编码utf-8/ 7位ASCII,长度最大2的32次方)string/unicode
bytes(最长2的32次方)py2(str)/py3(bytes)

protobuf demo

syntax = "proto3";  // 指定protobuf版本 不指定默认使用proto2

package grpc_py;  // 此文件的标识符,不添加也可以,以防止协议消息类型之间的名称冲突

message grpc_py_request {  // 定义消息类型
  string name = 1;  
  int32 age = 2;
  string phone = 3;
  bool avg = 4;
  //bytes image = 5;
}

// 数字标识用来标识你的字段,是解析的时候的唯一标识, 1-15占一个字节,16-2047占两字节
// 区间1-536870911  !!! 19000-19999 数字字段不可用 
// grpc_py_request/grpc_py_response 随便定义 
// 格式: 数据类型  命名 = 数字标识符(1-536870911)
message grpc_py_response {// 定义消息类型
  string name = 1;
  int32 age = 2;
  string phone = 3;
  bool avg = 4;
  //bytes image = 5;
}


// 创建连接方式 此方式是一元rpc模式
// RequestGrpcPy 随便定义 grpc_py_request是发送请求的数据
// returns 是返回 grpc_py_response 是接收的数据 
// 格式 rpc xx(request) returns (response) {}
service GrpcPy {
  rpc RequestGrpcPy(grpc_py_request) returns (grpc_py_response) {}
}

使用python 生产grpc文件
# 文件目录
├── grpcs
│   ├── __init__.py
└── protos
    └── grpc_py.proto

python -m  grpc_tools.protoc -I. --python_out=../grpcs --grpc_python_out=../grpcs ./grpc_py.proto
# 执行此代码需要和.proto文件在同一位置下
# --python_out=输出的文件位置 填写相对路径即可
# --grpc_python_out= 输出的文件位置 填写相对路径即可
# 尽量别将--python_out= 以及--grpc_python_out= 输出的文件和.proto文件放在同一目录下,否则会有导包的问题
# 执行命令后的文件目录
├── grpcs
│   ├── grpc_py_pb2_grpc.py
│   ├── grpc_py_pb2.py
│   ├── __init__.py
└── protos
    └── grpc_py.proto

编写基于grpc的grpc_server.py文件

# -*- coding:utf-8 -*-
from concurrent import futures

import grpc

import grpc_py_pb2
import grpc_py_pb2_grpc


class GrpcPy(grpc_py_pb2_grpc.GrpcPyServicer):
	
    def RequestGrpcPy(self, request, context):
        # RequestGrpcPy 此方法是proto文件中的接口函数 需要重写
        params = {
            "name": request.name,
            "age": request.age,
            "phone": request.phone,
            "avg": request.avg,
            # "image": request.image,
        }
        return grpc_py_pb2.grpc_py_response(**params)


def server():
    
    # 定义服务器并设置最大连接数,corcurrent.futures是一个并发库,类似于线程池的概念
    g_server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), 
                           options=[
                               ('grpc.max_send_message_length', 50*1024*1024),     # 50m
                               ('grpc.max_receive_message_length', 50*1024*1024)   # 50m
                               ])
   	# 创建一个服务器
    
    grpc_py_pb2_grpc.add_GrpcPyServicer_to_server(GrpcPy(), g_server)
    # 在服务器中添加派生的接口服务(自己实现了处理函数)
    
    g_server.add_insecure_port('0.0.0.0:50051')  
    # 指定端口以及IP
    
    g_server.start()
    #  启动服务器 start()是非阻塞的, 将实例化一个新线程来处理请求.
    
    g_server.wait_for_termination()
    # 阻塞调用线程,直到服务器终止

"""
此处是将文件的传输的阈值调大 默认是4M
options=[
	('grpc.max_send_message_length', 50*1024*1024),
	('grpc.max_receive_message_length',50*1024*1024)
	]
"""

if __name__ == '__main__':
    server()
	# 运行此文件即可,运行起服务端

编写基于grpc的grpc_client.py文件

# -*- coding:utf-8 -*-
import time

import grpc

import grpc_py_pb2
import grpc_py_pb2_grpc


def run():
    with grpc.insecure_channel("localhost:50051",
                               options=[
                                   ('grpc.max_send_message_length', 50 * 1024 * 1024),
                                   ('grpc.max_receive_message_length', 50 * 1024 * 1024)]) as channel:
        
        #  监听频道
        
        grpc_client = grpc_py_pb2_grpc.GrpcPyStub(channel)
        # 客户端使用Stub类发送请求,参数为频道,为了绑定链接
        
        start_time = time.time()
        params = {
            "name": "chengquan",
            "age": 25,
            "phone": "17744982585",
            "avg": True,
            "image": image_file
        }
        response = grpc_client.RequestGrpcPy(grpc_py_pb2.grpc_py_request(**params))
         # 返回的结果就是proto中定义的类
        
        print(f"response_time--------------------{time.time() - open_time}")
        print(f"response.name---------------------{response.name}")
        print(f"response.age---------------------{response.age}")
        print(f"response.phone---------------------{response.phone}")
        print(f"response.avg---------------------{response.avg}")
        print(f"spend_time-----------------{time.time() - start_time}")


if __name__ == '__main__':
    run()
	# 运行即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值