Python gRPC

  • 简介

    grpc 是google 开源的一款rpc服务框架,可以轻松的实现跨语言的微服务,将项目中的各个模块独立出来,单独部署,独立升级,也可以根据模块的情况进行不同语言的变成。

    gRPC也是一个C/S框架,使用的是HTTP2 协议进行通信。

  • 准备.proto文件

  syntax = "proto3";

  package order;
message OrderRequest {
string phone = 1;
string price = 2;
map<string, string> request_arg = 3;//便于字段扩展
} message JSONResponse{
string rst_string = 1; //统一返回json字符串作处理
} service OrderHandler {
// format a list of events.
rpc create_order (OrderRequest) returns (JSONResponse) {}
}

其中:

message: 定义数据结构

service: 定义接口的名字,参数,

  • 生成所需文件(服务器和客户端均需要)
python -m grpc_tools.protoc -I./ --python_out=./ --grpc_python_out=./ ./*.proto
  • 编写server端代码
 import time
import test_pb2_grpc
import grpc from concurrent import futures
from order.views import test import os class OrderHandler(test_pb2_grpc.OrderHandlerServicer):
def create_order(self, request, context):
return test(request, context) def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
test_pb2_grpc.add_OrderHandlerServicer_to_server(
OrderHandler(), server)
server.add_insecure_port('[::]:{}'.format(12006))
server.start()
try:
while True:
time.sleep(186400)
except KeyboardInterrupt:
server.stop(0)
serve()
  • 对应的views.py 文件
 from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
import test_pb2
import json
from django.http import HttpRequest def grpc_request(func):
“”“
将grpc请求重新构造成django requst,
并封装相应返回值
”“”
def f(request, context):
f = lambda x:{k:v for k,v in x.items()} if hasattr(x, 'items') else x
args = {i[0].name:f(i[1]) for i in request.ListFields() } # 构造django request 对象,并添加参数信息
dj_request = HttpRequest()
dj_request.GET = args
# dj_request.POST = args
# dj_request._body = json.dumps(args)
dj_request.META = args ret = func(dj_request) # 处理django的response 对象, 转换为grpc的对象
json_response = test_pb2.JSONResponse()
json_response.rst_string = ret.getvalue() return json_response
return f def check_inenty(func):
def f(request):
if "identy" not in request.META:
return JsonResponse(dict(status=403))
else:
return func(request)
return f @grpc_request
@check_inenty
def test(request):
return JsonResponse(dict(test=1, name="333"))
  • 编写客户端代码进行 测试 client.py
 import grpc
import test_pb2_grpc
import test_pb2 channel = grpc.insecure_channel("127.0.0.1:12006")
stub = test_pb2_grpc.OrderHandlerStub(channel)
ret = stub.create_order(test_pb2.OrderRequest(phone="12990", price="50")) print(ret.rst_string)
05-20 18:47