grpc例子

什么是RPC

RPC(Remote Procedure Call Protocol)-- 远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络协议的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

什么是gRPC

gRPC 是Google开源的一款高性能的 RPC 框架,它基于 ProtoBuf 序列化协议进行开发,支持多种开发语言(Golang、Python、Java、C/C++等)。gRPC 提供了一种简单的方法来定义服务,同时客户端可以充分利用 HTTP/2 stream 的特性,从而有助于节省带宽、降低 TCP 的连接次数、节省CPU的使用等。

本文参考官方文档[grpc.html],以及gRPC的GitHub开源项目grpc/grpc。并通过一个小demo展示框架用法。

安装gRPC及gRPC工具

pip install grpcio
pip install grpcio-tools

grpcio-tools包含了protobuf的编辑工具 protoc,用来根据 .proto 服务定义生成服务器端和客户端代码。

自定义 gRPC 接口

假定这里我们需要定义一个数据接收服务Receiver,用来接收客户端传递给服务器端的数据。

syntax = "proto3";
import "google/protobuf/struct.proto";

// 服务定义
service Receiver {
  rpc receive (Event) returns (Reply) {}
}

// 接收消息定义
message Event {
  string appid = 1;
  int32 xwhen = 2;
  string xwho = 3;
  string xwhat = 4;
  google.protobuf.Struct xcontext = 5;
}

// 返回消息定义
message Reply {
  int32 status = 1;
  string message = 2;
}

编译 proto 文件生成服务接口

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

这里会生成两个python文件:

receiver_pb2.py
receiver_pb2_grpc.py

编写Server端代码

# _*_ coding: utf-8 _*_

import grpc
import receiver_pb2
import receiver_pb2_grpc

import time
from concurrent import futures

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class Receiver(receiver_pb2_grpc.ReceiverServicer):

    # 重写父类方法,返回消息
    def receive(self, request, context):
        print('request:', request)
        return receiver_pb2.Reply(message='Hello, %s!' % request.xwho)


if __name__ == '__main__':
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    receiver_pb2_grpc.add_ReceiverServicer_to_server(Receiver(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    print('server start...')
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)

编写client端代码

# _*_ coding: utf-8 _*_

import grpc
import receiver_pb2
import receiver_pb2_grpc
from google.protobuf import struct_pb2


def run():
    channel = grpc.insecure_channel('localhost:50051')
    stub = receiver_pb2_grpc.ReceiverStub(channel)

    # 自定义struct结构
    struct = struct_pb2.Struct()
    struct['idfa'] = 'idfa1'
    struct['amount'] = 123

    response = stub.receive(receiver_pb2.Event(xwhat='install', appid='fuckgod', xwhen=123, xwho='jerry', xcontext=struct))
    print("client status: %s received: %s" % (response.status, response.message))


if __name__ == '__main__':
    run()

测试流程

(1)启动server:python server.py &

(2)运行client.py发送消息

server输出:

server start...
request: 
appid: "fuckgod"
xwhen: 123
xwho: "jerry"
xwhat: "install"
xcontext {
  fields {
    key: "amount"
    value {
      number_value: 123.0
    }
  }
  fields {
    key: "idfa"
    value {
      string_value: "idfa1"
    }
  }
}

client输出:

client status: 0 received: Hello, jerry!

表示测试成功。

转载自https://zhuanlan.zhihu.com/p/37158888

猜你喜欢

转载自blog.csdn.net/weixin_38383877/article/details/82152499