简介

在python中使用grpc和protobuf,比java和c#中使用要简单一些。只需要先安装grpcio包,然后就可以应用了。

安装

使用pip安装grpcio依赖包;

$ pip install grpcio
Collecting grpcioDownloading grpcio-1.7.0-cp27-cp27m-macosx_10_10_intel.whl (1.5MB)100% |████████████████████████████████| 1.5MB 18kB/s
Requirement already satisfied: enum34>=1.0.4 in /Users/David/anaconda2/lib/python2.7/site-packages (from grpcio)
Requirement already satisfied: futures>=2.2.0 in /Users/David/anaconda2/lib/python2.7/site-packages (from grpcio)
Requirement already satisfied: six>=1.5.2 in /Users/David/anaconda2/lib/python2.7/site-packages (from grpcio)
Collecting protobuf>=3.3.0 (from grpcio)Downloading protobuf-3.5.0-py2.py3-none-any.whl (388kB)100% |████████████████████████████████| 389kB 32kB/s
Requirement already satisfied: setuptools in /Users/David/anaconda2/lib/python2.7/site-packages (from protobuf>=3.3.0->grpcio)
Installing collected packages: protobuf, grpcio
Successfully installed grpcio-1.7.0 protobuf-3.5.0

安装时,自动地安装了protobuf工具包。

定义protobuf

下面定义一个简单的protobuf文件,在其中声明一个grpc服务。
创建一个proto目录,并在其中创建grpchello.proto文件,如下内容。

syntax = "proto3";
package grpcDemo;message HelloRequest {string name = 1;
}message HelloReply {string message = 1;
}service gRPC {rpc SayHello (HelloRequest) returns (HelloReply) {}
}

Note:
- 其实这个protobuf定义文件,在我们的java、c#版本示例中使用了,而且各版本的服务和客户端可以正常通行调用。

编译protobuf

使用protobuf的编译器,为我们生成python版本的Message定义和服务的架手脚。

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

在当前目录下,生成2个文件:
- grpchello_pb2.py
- grpchello_pb2_grpc.py

可以看看这2个文件:

首先消息定义文件:

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: grpchello.protoimport sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)_sym_db = _symbol_database.Default()DESCRIPTOR = _descriptor.FileDescriptor(name='grpchello.proto',package='grpcDemo',syntax='proto3',serialized_pb=_b('\n\x0fgrpchello.proto\x12\x08grpcDemo\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2B\n\x04gRPC\x12:\n\x08SayHello\x12\x16.grpcDemo.HelloRequest\x1a\x14.grpcDemo.HelloReply\"\x00\x62\x06proto3')
)_HELLOREQUEST = _descriptor.Descriptor(name='HelloRequest',full_name='grpcDemo.HelloRequest',filename=None,file=DESCRIPTOR,containing_type=None,fields=[_descriptor.FieldDescriptor(name='name', full_name='grpcDemo.HelloRequest.name', index=0,number=1, type=9, cpp_type=9, label=1,has_default_value=False, default_value=_b("").decode('utf-8'),message_type=None, enum_type=None, containing_type=None,is_extension=False, extension_scope=None,options=None),],extensions=[],nested_types=[],enum_types=[],options=None,is_extendable=False,syntax='proto3',extension_ranges=[],oneofs=[],serialized_start=29,serialized_end=57,
)_HELLOREPLY = _descriptor.Descriptor(name='HelloReply',full_name='grpcDemo.HelloReply',filename=None,file=DESCRIPTOR,containing_type=None,fields=[_descriptor.FieldDescriptor(name='message', full_name='grpcDemo.HelloReply.message', index=0,number=1, type=9, cpp_type=9, label=1,has_default_value=False, default_value=_b("").decode('utf-8'),message_type=None, enum_type=None, containing_type=None,is_extension=False, extension_scope=None,options=None),],extensions=[],nested_types=[],enum_types=[],options=None,is_extendable=False,syntax='proto3',extension_ranges=[],oneofs=[],serialized_start=59,serialized_end=88,
)DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
_sym_db.RegisterFileDescriptor(DESCRIPTOR)HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(DESCRIPTOR = _HELLOREQUEST,__module__ = 'grpchello_pb2'# @@protoc_insertion_point(class_scope:grpcDemo.HelloRequest)))
_sym_db.RegisterMessage(HelloRequest)HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(DESCRIPTOR = _HELLOREPLY,__module__ = 'grpchello_pb2'# @@protoc_insertion_point(class_scope:grpcDemo.HelloReply)))
_sym_db.RegisterMessage(HelloReply)_GRPC = _descriptor.ServiceDescriptor(name='gRPC',full_name='grpcDemo.gRPC',file=DESCRIPTOR,index=0,options=None,serialized_start=90,serialized_end=156,methods=[_descriptor.MethodDescriptor(name='SayHello',full_name='grpcDemo.gRPC.SayHello',index=0,containing_service=None,input_type=_HELLOREQUEST,output_type=_HELLOREPLY,options=None,),
])
_sym_db.RegisterServiceDescriptor(_GRPC)DESCRIPTOR.services_by_name['gRPC'] = _GRPC# @@protoc_insertion_point(module_scope)

在看看grpc服务定义

# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpcimport grpchello_pb2 as grpchello__pb2class gRPCStub(object):# missing associated documentation comment in .proto filepassdef __init__(self, channel):"""Constructor.Args:channel: A grpc.Channel."""self.SayHello = channel.unary_unary('/grpcDemo.gRPC/SayHello',request_serializer=grpchello__pb2.HelloRequest.SerializeToString,response_deserializer=grpchello__pb2.HelloReply.FromString,)class gRPCServicer(object):# missing associated documentation comment in .proto filepassdef SayHello(self, request, context):# missing associated documentation comment in .proto filepasscontext.set_code(grpc.StatusCode.UNIMPLEMENTED)context.set_details('Method not implemented!')raise NotImplementedError('Method not implemented!')def add_gRPCServicer_to_server(servicer, server):rpc_method_handlers = {'SayHello': grpc.unary_unary_rpc_method_handler(servicer.SayHello,request_deserializer=grpchello__pb2.HelloRequest.FromString,response_serializer=grpchello__pb2.HelloReply.SerializeToString,),}generic_handler = grpc.method_handlers_generic_handler('grpcDemo.gRPC', rpc_method_handlers)server.add_generic_rpc_handlers((generic_handler,))

简单看下:
- 在grpc服务架手脚定义中,定义了gRPCStub,这是给client端使用,调用grpc服务的。
- 定义的服务类gRPCServicer,方法SayHello需要我们在子类中进行实现。定义的add_gRPCServicer_to_server方法,用于把实现的类和grpc API调用注册起来。

这里使用的几个主要方法(类):
- grpc.server – Creates a Server with which RPCs can be serviced
- grpc.method_handlers_generic_handler – Creates a GenericRpcHandler from RpcMethodHandlers.
- grpc.unary_unary_rpc_method_handler – Creates an RpcMethodHandler for a unary-unary RPC method.

实现服务

在我们的实现服务的类中,使用服务方法,并在网络中暴露出来。

# -*- coding: utf-8 -*-
import grpc
import time
from concurrent import futures
import grpchello_pb2, grpchello_pb2_grpc_HOST = 'localhost'
_PORT = '8188'_ONE_DAY_IN_SECONDS = 60 * 60 * 24class gRPCServicerImpl(grpchello_pb2_grpc.gRPCServicer):def SayHello(self, request, context):print ("called with " + request.name)return grpchello_pb2.HelloReply(message='Hello, %s!' % request.name)def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))grpchello_pb2_grpc.add_gRPCServicer_to_server(gRPCServicerImpl(), server)server.add_insecure_port('[::]:'+_PORT)server.start()try:while True:time.sleep(_ONE_DAY_IN_SECONDS)except KeyboardInterrupt:server.stop(0)if __name__ == '__main__':serve()

这里包括2个实现:
- 1、在grpc的API的实现(服务实现类)gRPCServicerImpl中,实现SayHello方法。
- 2、然后,定义网络服务和端口,把grpc的API注册到网络服务的处理上。这里简单利用了grpc.server类。

使用客户端client

在客户端,调用grpc的服务API。

# -*- coding: utf-8 -*-
"""The Python implementation of the gRPC client."""
from __future__ import print_function
import grpc
from grpchello_pb2  import *    ## or import grpchello_pb2
from grpchello_pb2_grpc import *
## No grpcDemo!  from grpcDemo import grpchello_pb2, grpchello_pb2_grpc #error!_PORT = '8188'def run():conn = grpc.insecure_channel(_HOST + ':' + _PORT)client = gRPCStub(channel=conn)response = client.SayHello(HelloRequest(name='David'))print("received: " + response.message)##
if __name__ == '__main__':if len(sys.argv)== 2:print (sys.argv[1])_HOST = sys.argv[1]else:_HOST = 'localhost'#    run()

说明:
- 1、 def insecure_channel(target, options=None):
– Creates an insecure Channel to a server.
- 2、 客户端使用服务的Stub,调用API。

测试

分别启动服务,然后再启动客户端,可以看到调用结果。
也可以启动java、c#版本的grpc服务端、客户端,都能调用成功。

在python中使用grpc和protobuf相关推荐

  1. 在C#中使用gRPC及protobuf简介

    简介 gRPC提供了很多的语言开发包,C#也可以很容易使用.结合使用protobuf及其编译器,很容易地生成了gRPC的服务stub和proxy. 在CSharp中使用gRPC和Protobuf,可以 ...

  2. python grpc 并发_在Python中使用gRPC的方法示例【h】

    本文介绍了在Python中使用gRPC的方法示例,分享给大家,具体如下: 使用Protocol Buffers的跨平台RPC系统. 安装 使用 pip gRPC由两个部分构成,grpcio 和 gRP ...

  3. python中使用grpc方法示例_在Python中使用gRPC的方法示例

    本文介绍了在Python中使用gRPC的方法示例,分享给大家,具体如下: 使用Protocol Buffers的跨平台RPC系统. 安装 使用 pip pip install grpcio pip i ...

  4. Go实战--golang中使用gRPC和Protobuf实现高性能api(golang/protobuf、google.golang.org/grpc)

    生命不止,继续 go go go !!! 号外号外,插播一条广告,通过博客的uv可以看到周五,程序员是不怎么干活的: 本篇博客,使用gRPC和Protobuf,实现所谓的高性能api. protobu ...

  5. java中使用grpc和protobuf

    第一步 使用maven,比较简单.依赖项中添加: <dependency><groupId>io.grpc</groupId><artifactId>g ...

  6. grpc 可以传递context嘛_Python中使用gRPC方法示例

    本文介绍了在Python中使用gRPC的方法示例, 具体如下: 使用 Protocol Buffers 的跨平台RPC系统. 安装 使用 pip pip install grpciopip insta ...

  7. 在Python中使用Protobuf

    前言 之前做游戏开发时,游戏服务端与前端采用Protobuf来进行数据传输,为了避免被人恶意破解,还对Protobuf产生的数据做了简单的偏移处理.最近又要用到Protobuf了,所以简单记录一下相关 ...

  8. python中使用 protocol buffer(Protobuf)

    项目中引入proto的依赖 [两种方法]: 方法1. 官网下载对应的语言包,https://github.com/protocolbuffers/protobuf/releases 这里选择pytho ...

  9. python缓冲区_如何在Python中使用Google的协议缓冲区

    python缓冲区 When people who speak different languages get together and talk, they try to use a languag ...

最新文章

  1. 阿里开源的缓存框架JetCache,实现spring二级缓存
  2. ASP.NET2.0_执行页面发送的强类型方法与弱类型方法
  3. 【Linux网络编程】并发服务器之select模型
  4. NHibernate之旅(7):初探NHibernate中的并发控制
  5. 案例:无人测量船水库水下地形测量及库容量计算
  6. java国际化 英语的标识符_(转)Java 国际化
  7. [Fatal Error] :3:13: Open quote is expected for attribute {1} associated with an element type i...
  8. BMP、GIF、TIFF、PNG、JPG和SVG格式图像的特点
  9. dump日志分析工具
  10. js中操作cookie
  11. 栈和队列的应用(迷宫问题)
  12. 矩阵乘法求解多项式递推问题
  13. Shodan Hacking
  14. 设计模式学习难度系数排名
  15. (学习日志)MAYA基础设置
  16. 中国RFID市场规模及结构浅析
  17. 新冠疫情防控背后有哪些鲜为人知的技术?
  18. 关于gcc :multiple definition of
  19. 邵阳一中2021高考成绩查询,2021年邵阳高考状元名单公布,邵阳文理科状元是谁多少分...
  20. VM虚拟机adb调试手机

热门文章

  1. php 实现同一个账号同时只能一个人登录
  2. IP5的接口模式运行测试
  3. powerdesigner奇淫技
  4. Error:Unable to capture view hierarchy
  5. supervisor进程管理工具
  6. 晒晒女儿学国画一学期的成果
  7. js利用tab键切换当前页面_JS实现的tab切换并显示相应内容模块功能示例
  8. python中hashset_python中的集合
  9. python打包安卓的方法_30个你想打包带走的Python技巧(下)
  10. flink读mysql速度怎么样_[DB] Flink 读 MySQL