grpc_python分析起步

工具要求

  • ubuntu20.04
  • Python 3.5 或更高版本
  • pip 9.0.1 或更高版本

安装grpc

python -m pip install grpcio

安装grpc工具

python -m pip install grpcio-tools

下载示例代码

git clone -b v1.42.0 https://github.com/grpc/grpc

文件结构分析

  • helloworld.proto:定义服务
    • (自动生成)hello_pb2.py:包含我们生成的请求和响应类
    • (自动生成)hello_pb2_grpc.py:包含我们生成的客户端和服务器类的内容,调用了hello_pb2.py
  • greeter_server.py:服务器
  • greeter_client.py:客户端

helloworld.proto

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}
// The response message containing the greetings
message HelloReply {
  string message = 1;
}

python -m grpc_tools.protoc -I…/…/protos –python_out=. –grpc_python_out=. …/…/protos/helloworld.proto
分别是helloworld.proto所在的文件夹路径,生成pb2、pb2_grpc文件的路径,helloworld.proto的完整路径。

helloworld_pb2_grpc.py

# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import helloworld_pb2 as helloworld__pb2

class GreeterStub(object):
    """The greeting service definition.
    """
    def __init__(self, channel):
        """Constructor.
        Args:
            channel: A grpc.Channel.
        """
        self.SayHello = channel.unary_unary(
                '/helloworld.Greeter/SayHello',
                request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
                response_deserializer=helloworld__pb2.HelloReply.FromString,
                )
class GreeterServicer(object):
    """The greeting service definition.
    """
    def SayHello(self, request, context):
        """Sends a greeting
        """
        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
        context.set_details('Method not implemented!')
        raise NotImplementedError('Method not implemented!')

def add_GreeterServicer_to_server(servicer, server):
    rpc_method_handlers = {
            'SayHello': grpc.unary_unary_rpc_method_handler(
                    servicer.SayHello,
                    request_deserializer=helloworld__pb2.HelloRequest.FromString,
                    response_serializer=helloworld__pb2.HelloReply.SerializeToString,
            ),
    }
    generic_handler = grpc.method_handlers_generic_handler(
            'helloworld.Greeter', rpc_method_handlers)
    server.add_generic_rpc_handlers((generic_handler,))

 # This class is part of an EXPERIMENTAL API.
class Greeter(object):
    """The greeting service definition.
    """
    @staticmethod
    def SayHello(request,
            target,
            options=(),
            channel_credentials=None,
            call_credentials=None,
            insecure=False,
            compression=None,
            wait_for_ready=None,
            timeout=None,
            metadata=None):
        return grpc.experimental.unary_unary(request, target, '/helloworld.Greeter/SayHello',
            helloworld__pb2.HelloRequest.SerializeToString,
            helloworld__pb2.HelloReply.FromString,
            options, channel_credentials,
            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

类图:

object GreeterStub +__init__(self,channel) +SatHello() GreeterServicer +SayHello(self,request,context) Greeter +SayHello()

关键全局函数:
add_GreeterServicer_to_server(servicer, server)

greeter_server.py

"""The Python implementation of the GRPC helloworld.Greeter server."""

from concurrent import futures
import logging

import grpc
import helloworld_pb2
import helloworld_pb2_grpc


class Greeter(helloworld_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) #返回结果,使用到了pb2

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()


if __name__ == '__main__':
    logging.basicConfig()
    serve()
GreeterServicer Greeter +SayHello()

关键全局函数:
serve()

greeter_client.py

from __future__ import print_function
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc

def run():
  channel = grpc.insecure_channel('localhost:50051')
  stub = helloworld_pb2_grpc.GreeterStub(channel)
  response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) #关键,发送request,使用到了pb2
  print("Greeter client received: " + response.message) 
  
if __name__ == '__main__':
    logging.basicConfig()
    run()

基本通信流程

object GreeterStub +__init__(self,channel) +SatHello() GreeterServicer +SayHello(self,request,context) Greeter +SayHello() grpc_server server add_GreeterServicer_to_server_function server_Greeter +SayHello() stub used Linked(Communication)

greeter_client.py调用stub.SayHello(helloworld_pb2.HelloRequest(name=‘you’)),向server发送请求,传到了greeter_server.py中的Greeter中的SayHello(),执行return helloworld_pb2.HelloReply(message=‘Hello, %s!’ % request.name),此时stub.SayHello()函数返回,response得到结果。

client server ①response=stub.SayHello(helloworld_pb2.HelloRequest(name='you')) ②return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) client server

问题:helloworld_pb2.HelloRequest()函数和helloworld_pb2.HelloReply()函数?
回顾helloworld.proto:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
  string name = 1;
}
message HelloReply {
  string message = 1;
}

操作①实际上是:helloworld_pb2_grpc.py中GreeterStub类的SayHello()函数:channel.unary_unary(
‘/helloworld.Greeter/SayHello’,
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
)
操作②是:greeter_server中的Greeter类的SayHello()函数,该类继承于helloworld_pb2_grpc.py中的GreeterServicer类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值