记python使用grpc

using grpc in Python

gRPC是基于http/2的RPC框架,使用ProtoBuf作为底层数据序列化。Nginx服务器2018年3月17日引入gRPC支持。

gRPC 是用来实现跨语言通信的。比如在你的某个功能里需要用的同事写的接口,而你们俩又不是同一种语言。此时有两种方案,一是使用.so 文件;另一种则是使用 RPC 框架。

创建一个grpc_demo项目,结构如下

grpc_demo/
├── client
│ └── client.py
├── example
│ └── data.proto
└── server
​ └── server.py

  • client目录下的client.py实现了客户端用于发送数据并打印接收到server端处理后的数据
  • server目录下的server.py实现了server端用于接收客户端发送的数据,并对数据进行简单处理后返回给客户端
  • example包用于编写proto文件并生成data接口

grpc安装

  • 安装gRPC

    pip install grpcio

  • 安装 ProtoBuf 相关的 python 依赖库

    pip install protobuf

  • 安装 python grpc 的 protobuf 编译工具

    pip install grpcio-tools

定义gRPC接口

data.proto文件,service关键字就是定义接口,message定义数据结构

syntax = "proto3";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
    string message = 2;
    string location = 3;
    string ip = 4;
}

message HelloReply {
    string name = 1;
    string message = 2;
    string location = 3;
    string ip = 4;
}

编译protobuf生成所需文件(服务端和客户端都需要)

# mkdir gen-py
# python -m grpc_tools.protoc --proto_path=./  --python_out=./gen_py --grpc_python_out=./gen_py ./data.proto

在gen-py目录下生成data_pb2_grpc.py和data_pb2.py两个文件。

生成后完整目录结构:

grpc_demo
├── client
│ └── client.py
├── example
│ ├── data.proto
│ └── gen_py
│ ├── data_pb2_grpc.py
│ └── data_pb2.py
└── server
​ └── server.py

服务端实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.path.append('../example/gen_py')
import grpc
import time
from concurrent import futures
import data_pb2
import data_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_HOST = "127.0.0.1"
_PORT = "19999"

class HelloWorld(data_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        print("request: " + str(request))
        return data_pb2.HelloReply(message='%s, %s!' % (request.message, request.name))

def server():
    grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
    data_pb2_grpc.add_GreeterServicer_to_server(HelloWorld(), grpcServer)
    grpcServer.add_insecure_port("{0}:{1}".format(_HOST, _PORT))
    grpcServer.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        grpcServer.stop(0)


if __name__ == '__main__':
    server()

客户端实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.path.append("../example/gen_py")
import grpc
import data_pb2
import data_pb2_grpc

_HOST = '127.0.0.1'
_PORT = '19999'


def run():
    with grpc.insecure_channel("{0}:{1}".format(_HOST, _PORT)) as channel:
        client = data_pb2_grpc.GreeterStub(channel=channel)
        response = client.SayHello(data_pb2.HelloRequest(name='you', message='hey guys'))
    print("received: " + response.message)


if __name__ == '__main__':
    run()
    
 #channel = grpc.insecure_channel("{0}:{1}".format(_HOST, _PORT))
 #client = data_pb2_grpc.GreeterStub(channel=channel)
 #response = client.SayHello(data_pb2.HelloRequest(name='you', message='hey guys'))
 #print("received: " + response.message)

参考:

https://blog.codeship.com/using-grpc-in-python/

https://github.com/geekan/grpc-python-demos

http://doc.oschina.net/grpc

posted @ 2018-12-07 15:22  村口王铁匠  阅读(3558)  评论(0编辑  收藏  举报