简介:

gRPC 是Google发布的一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。gRPC提供了支持多种编程语言的、对网络设备进行配置和纳管的方法。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持。

gRPC

实现:

环境:

Python 3.8 or Anaconda3

grpcio

protobuf

通过pip安装依赖

pip install grpcio

pip install protobuf

pip install grpcio-tools

实现proto文件:

gRPC通过 protocol buffers来定义 gRPC service 和方法 request 以及 response 的类型。

要定义请求的和响应的数据类型,需要在 .proto 文件中指定关键字 message。要定义一个服务,需要 .proto 文件中指定关键字 service。

gRPC 允许你定义四类服务方法,通过stream关键字来控制:

一元模式RPC,即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。

服务端流模式 RPC,即客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。

客户端流模式 RPC,即客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。

双向流模式 RPC,即两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。

如下一个简单地grpc proto文件demo.proto,定义了数据传输的格式和四种不同的服务类型:

// protocal buffers 语法版本声明

syntax="proto3";

// message 定义了传输数据的格式,等号之后的数字是字段编号,每个编号都是唯一的。message结构类似于结构体

message Request {

int32 client_id = 1;

string request_data = 2;

}

message Response {

int32 server_id = 1;

string response_data = 2;

}

// 定义gRPC服务方法

service gRPCDemo {

// 一元模式(在一次调用中, 客户端只能向服务器传输一次请求数据, 服务器也只能返回一次响应)

rpc SimpleMethod(Request) returns (Response);

// 客户端流模式(在一次调用中, 客户端可以多次向服务器传输数据, 但是服务器只能返回一次响应)

rpc ClientStreamMethod(stream Request) returns (Response);

// 服务端流模式(在一次调用中, 客户端只能一次向服务器传输数据, 但是服务器可以多次返回响应)

rpc ServerStreamMethod(Request) returns (stream Response);

// 双向流模式 (在一次调用中, 客户端和服务器都可以向对方多次收发数据)

rpc BidirectStremMethod(stream Request) returns (stream Response);

}

通过下列命令可以根据demo.proto自动生成客户端和服务端的代码,我们需要做的只是继承里面实现具体处理逻辑的方法并实现他们,而不需要关系具体的传输逻辑。

python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./demo.proto

执行后会生成demo_pb2.py和demo_pb2_grpc.py两个文件,里面分别实现了消息类、服务的抽象类和客户端应用使用的函数。

实现服务端与客户端:

服务端:

继承gRPCDemoServicer的抽象类,实现proto里定义的函数。一元模式接收和返回的是request类和response类,流模式接收和返回的是类的迭代器。

import grpc

import demo_pb2

import demo_pb2_grpc

from concurrent import futures

from threading import Thread

SERVER_ID = 1

SERVER_ADDRESS = "localhost:50051"

class DemoService(demo_pb2_grpc.gRPCDemoServicer):

def SimpleMethod(self, request, context):

print('call simple method from client {}'.format(request.client_id))

print('data details: {}'.format(request.request_data))

reponse = demo_pb2.Response(server_id=SERVER_ID, response_data='simple data')

return reponse

def ClientStreamMethod(self, request_iterator, context):

for i, request in enumerate(request_iterator):

print('data {} details: {}'.format(i, request.request_data))

reponse = demo_pb2.Response(server_id=SERVER_ID, response_data='client stream data')

return reponse

def ServerStreamMethod(self, request, context):

for i in range(5):

response = demo_pb2.Response(server_id=SERVER_ID, response_data='server stream data {}'.format(i))

yield response

def BidirectStremMethod(self, request_iterator, context):

# 开启一个子线程去接收数据

def parse_request():

for request in request_iterator:

print("recv from client(%d), message= %s" %

(request.client_id, request.request_data))

t = Thread(target=parse_request)

t.start()

for i in range(5):

yield demo_pb2.Response(

server_id=SERVER_ID,

response_data=("send by Python server, message= %d" % i))

t.join()

def main():

server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

demo_pb2_grpc.add_gRPCDemoServicer_to_server(DemoService(), server)

server.add_insecure_port(SERVER_ADDRESS)

print("------------------start Python GRPC server")

server.start()

server.wait_for_termination()

if __name__ == '__main__':

main()

客户端:

与服务端通过指定端口建立通道,通过gRPCDemoStub类实例化一个客户端向服务端发送请求。客户端可以像调用本地函数一样来调用服务端的函数。

import grpc

import time

import demo_pb2

import demo_pb2_grpc

client_ID = 1

SERVER_ADDRESS = "localhost:50051"

def simple_method(stub):

request = demo_pb2.Request(client_id=client_ID, request_data='simple call')

response = stub.SimpleMethod(request)

print(response.response_data)

def client_stream_method(stub):

# 创建一个生成器

def request_messages():

for i in range(5):

request = demo_pb2.Request(

client_id=client_ID,

request_data=("called by Python client, message:%d" % i))

yield request

response = stub.ClientStreamingMethod(request_messages())

def server_stream_method(stub):

request = demo_pb2.Request(client_id=client_ID, request_data='server stream call')

response = stub.ServerStreamMethod(request)

for res in response:

print(res.response_data)

def bidirectional_streaming_method(stub):

print("--------------Call BidirectionalStreamingMethod Begin---------------")

# 创建一个生成器

def request_messages():

for i in range(5):

request = demo_pb2.Request(

client_id=client_ID,

request_data=("called by Python client, message: %d" % i))

yield request

time.sleep(1)

response_iterator = stub.BidirectionalStreamingMethod(request_messages())

for response in response_iterator:

print("recv from server(%d), message=%s" % (response.server_id, response.response_data))

print("--------------Call BidirectionalStreamingMethod Over---------------")

def main():

MAX_MESSAGE_LENGTH = 1024 * 1024 * 10

options = [('grpc.max_send_message_length', MAX_MESSAGE_LENGTH),

('grpc.max_receive_message_length', MAX_MESSAGE_LENGTH)]

with grpc.insecure_channel(SERVER_ADDRESS, options=options) as channel:

stub = demo_pb2_grpc.gRPCDemoStub(channel)

simple_method(stub)

# server_stream_method(stub)

if __name__ == '__main__':

main()

通信测试:

一元模式:

服务端挂起在50051端口等待请求,客户端发起一次请求服务端对应的函数就被调用一次。

server

服务端流模式:

服务端挂起在50051端口等待请求,客户端发起多次请求,服务端函数仅调用一次,将客户端的多次请求当做一个迭代器来处理。

client

server

grpc python stream_Python gRPC笔记相关推荐

  1. grpc python stream_grpc| python 实战 grpc【h】

    title: grpc| python 实战 grpc description: 只要代码可以跑起来, 很多难题都会迎刃而解. so, keep coding and stay hungry. 之前用 ...

  2. grpc环境配置 python_grpc| python 实战 grpc【h】

    title: grpc| python 实战 grpc description: 只要代码可以跑起来, 很多难题都会迎刃而解. so, keep coding and stay hungry. 之前用 ...

  3. python grpc 并发_用Python进行gRPC接口测试(二)

    今天将继续为大家带来用Python进行gRPC接口测试的续集,上次主要讲了一下前期准备工作和简单RPC通信方式的实现,这次我们将着眼于另一类gRPC接口的通信形式--流式RPC. 一.流式RPC的三种 ...

  4. 技术实践:教你用Python搭建gRPC服务

    摘要:gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf序列化协议开发,且支持众多开发语言. 本文分享自华为云社区& ...

  5. 小猿圈python_小猿圈Python配置gRPC环境

    现在学习Python的同学有没有遇到过一些问题?有没有问题不知道怎么去解决呢?下面小猿圈Python讲师每天为你讲解一个知识点,今天讲解的是Python配置gRPC环境,希望对你有所帮助. gRPC是 ...

  6. gRPC Python 的文档

    link: https://grpc.github.io/grpc/python/

  7. gRPC python实现文件上传,以及使用流式通信上传超大文件

    通过gRPC接口上传文件的优点 使用gRPC上传文件有许多优点: 实现简单.就是简单地写个接口,而且rprotobuf 定义好了参数,Server端与Client对接方便 无须部署额外软件.生产环境不 ...

  8. grpc:hello grpc

    安装grpc gRPC,即google Remote Procedure Call Protocol:在gRPC里,客户端可以直接调用不同机器上的服务应用的方法,就像本地对象一样,所以创建分布式应用和 ...

  9. php grpc,PHP配置grpc

    //开始之前我们说一下我遇到的坑,我自己安装了php7.3,系统自带了php7.0:我为pjp7.3安装扩展,但是操作的时候老是访问系统自带的php7.0,后来我把系统自带的php7.0的可执行文件( ...

最新文章

  1. HDU2112(Flody算法和Dijstra算法)
  2. Mysql (InnoDB引擎)聚集索引和辅助索引
  3. 软件工程个人作业03
  4. F# 4.0于全平台发布
  5. android sqlite3_open_v2( data/data//database ,handle,1,null)
  6. html5 canvas获取坐标系,HTML5 Canvas坐标变换
  7. 那些《西游记》中你不知道的野史,信不信由你
  8. C++中默认构造函数使用时的要点
  9. linux 查看 pppoe dns,Ubuntu 7.04中ADSL拨号上网及DNS设置
  10. PHP最彻底的退出登录,清除session、cookie的代码
  11. HDU3364 Lanterns
  12. keli4 指针运算_如何在KEIL中使用MicroLIB | 学步园
  13. 华南理工会计学计算机答案,2020华工会计学原理平时作业答案
  14. mysql 8.XXX zip版的安装使用
  15. MyBatis 多表关联查询
  16. 鼠标事件,显示悬浮窗
  17. k8s之pod和pod探针
  18. play-framework的安装配置(OS X和windows版)
  19. Android 使用MediaPlayer播放音频详解
  20. 从 DAU 5 万到用户数破亿,揭秘腾讯会议增长背后的技术实践

热门文章

  1. MIC检测方式(六)
  2. PCM data flow - 2 - ASoC data structure
  3. 使用Android 隐藏API和内部 API
  4. 使用NDK生成native C/C++的可执行程序
  5. 毕业5年决定人的一生-- 大家千万不要错过这篇文章
  6. ffmpeg一些filter用法、以及一些功能命令
  7. Vue之import
  8. C#之Bcd码时间转成ToDateTime
  9. 查看Oracle的procedures,Oracle通过shell脚本查看procedure的信息
  10. java编程基础码_【Java编程的逻辑】编程基础