python中使用grpc

###简介
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

###gRPC 是什么?
在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

正则图

1
2
3
pip install grpc
pip install grpcio
pip install grpcio-tools

####编写数据data.proto

1
2
3
4
5
6
7
8
syntax = "proto3";
package example;
message Data {
string text = 1;
}
service FormatData {
rpc DoFormat(Data) returns (Data){}
}

####生成客户端和服务器端代码

1
python -m grpc_tools.protoc -I. –python_out=. –grpc_python_out=. data.proto

###客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import grpc

import data_pb2_grpc
import data_pb2

_HOST = '0.0.0.0'
_PORT = '8080'

def run():
conn = grpc.insecure_channel(_HOST + ':' + _PORT)
client = data_pb2_grpc.FormatDataStub(channel=conn)
response = client.DoFormat(data_pb2.Data(text='hello,world!'))
print("received: " + response.text)

if __name__ == '__main__':
run()

###服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import time

import grpc
from concurrent import futures

import data_pb2_grpc
import data_pb2

_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_HOST = '0.0.0.0'
_PORT = '8080'

class FormatData(data_pb2_grpc.FormatDataServicer):
def DoFormat(self, request, context):
str = request.text
return data_pb2.Data(text=str.upper())

def serve():
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:
print 'enter try'
while True:
print 'enter True'
time.sleep(_ONE_DAY_IN_SECONDS)
print 'after time.sleep'
except KeyboardInterrupt:
grpcServer.stop(0)

if __name__ == '__main__':
serve()