前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Python】建立gRPC服务端与.Net Core 客户端

【Python】建立gRPC服务端与.Net Core 客户端

作者头像
DDGarfield
发布2022-06-23 17:46:36
6850
发布2022-06-23 17:46:36
举报
文章被收录于专栏:加菲的博客加菲的博客

由于需要接入其他平台的OAuth 2.0,还要提供RESTful API获取VMware vSphere的数据,这块内容,.net core我更熟悉,所以锁定ASP.NET Core,通过上两篇,我们知道这里只能通过python去获取数据了,那么我面临的问题就是python.net core的数据通信:

  • 方法一:使用Python的web轻量级框架Flask提供api,供asp.net core调用
  • 方法二:使用Python建立gRPC的服务端,供asp.net core调用

我选择后者,因为之前有gRPC的基础。

1.更新pip

代码语言:javascript
复制
python -m pip install --upgrade pip

2.安装grpc

代码语言:javascript
复制
python -m pip install grpcio

3.安装gRPC-tool

代码语言:javascript
复制
python -m pip install grpcio-tools

4.编写.proto文件

如果对ProtoBuf不熟悉,请参考另外一篇博文【gRPC】ProtoBuf 语言快速学习指南

主要是要记住几个关键要点:

  • service
代码语言:javascript
复制
   service Query {
     rpc ListHostStat (google.protobuf.Empty) returns (HostStatReply) {}
   }
   ```
- message

 - 作为`rpc`服务的请求和返回

```protobuf
syntax = "proto3";

import "google/protobuf/empty.proto";

option csharp_namespace  = "Grpc.VmwareVsphere";

package Vcenter;

service Query {
 rpc ListHostStat (google.protobuf.Empty) returns (HostStatReply) {}
}

message HostStatReply {
   int32  abnormalHostAmount = 1;
   int32  hostAmount = 2;
   int32  normalHostAmount = 3;
}

5.生成python服务端代码

代码语言:javascript
复制
cd python-dir
python -m grpc_tools.protoc -I ../protos --python_out=. --grpc_python_out=. ../protos/vcenter.proto

这里会生成两个python文件

[proto-file-name]_pb2.py

[proto-file-name]_pb2_grpc.py

6.编写服务端代码

1. 引入grpc包与生成的python文件

代码语言:javascript
复制
import grpc
import vcenter_pb2
import vcenter_pb2_grpc

官方还引入了

代码语言:javascript
复制
from concurrent import futures
import logging

第一个不知道在干啥,先不细究,第二个应该是写日志的

2. 实现服务端类

代码语言:javascript
复制
class Query(vcenter_pb2_grpc.QueryServicer):
    def ListHostStat(self, request, context):
        hostquery = VmwareHost(host, user, pwd, port)
        hostquery.list_host_state_num()
        return vcenter_pb2.HostStatReply(
            abnormalHostAmount=hostquery.abnormalHostAmount,
            hostAmount=hostquery.hostAmount,
            normalHostAmount=hostquery.normalHostAmount,
        )

类比C#实现服务端类,大致内容就是继承一个父类,然后重写基类方法:

代码语言:javascript
复制
class QueryImpl : Query.QueryBase
{
    public override Task<HostStatReply> ListHostStat(NoPara request, ServerCallContext context)
    {
        return Task.FromResult(new HostStatReply { ... });
    }
}

整体看下python服务端代码吧

代码语言:javascript
复制
from concurrent import futures
import logging

import grpc
import vcenter_pb2
import vcenter_pb2_grpc
from vmware_query import VmwareHost


class Query(vcenter_pb2_grpc.QueryServicer):
    def ListHostStat(self, request, context):
        hostquery = VmwareHost(host, user, pwd, port)
        hostquery.list_host_state_num()
        return vcenter_pb2.HostStatReply(
            abnormalHostAmount=hostquery.abnormalHostAmount,
            hostAmount=hostquery.hostAmount,
            normalHostAmount=hostquery.normalHostAmount,
        )

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    vcenter_pb2_grpc.add_QueryServicer_to_server(Query(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    print("grpc server start success..  listen port:50051")
    server.wait_for_termination()


host = "192.168.0.110"
user = "....l"
pwd = "....!"
port = 443
if __name__ == '__main__':
    logging.basicConfig()
    serve()

7.启动

代码语言:javascript
复制
def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    vcenter_pb2_grpc.add_QueryServicer_to_server(Query(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    print("grpc server start success..  listen port:50051")
    server.wait_for_termination()

类比C#实现的服务端

代码语言:javascript
复制
Server server = new Server
{
    Services = { Query.BindService(new QueryImpl()) },
    Ports = { new ServerPort("localhost", 50051, ServerCredentials.Insecure) }
};
server.Start();

Console.WriteLine("Query server listening on port " + 50051);
Console.WriteLine("Press any key to stop the server...");
Console.ReadKey();

server.ShutdownAsync().Wait();

8.编写客户端代码

客户端是ASP.NET Core,在WebAPI中调用gRPC服务

1. 安装nuget包

参考【gRPC】 在.Net core中使用gRPC 4.1 安装包

2.编辑csproj文件

引入与服务端相同的proto文件

代码语言:javascript
复制
  <ItemGroup>
    <Protobuf Include="..\..\protos\*.proto" GrpcServices="Client" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" />
  </ItemGroup>

3.编码

代码语言:javascript
复制
[HttpGet]
[Produces("application/json")]
public async Task<Host> GetHostAsync()
{
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
    var channel = GrpcChannel.ForAddress("http://localhost:50051");
    var queryClient = new QueryClient(channel);
    var reply = await queryClient.ListHostStatAsync(new Grpc.VmwareVsphere.NoPara());
    Console.WriteLine("StatService 服务返回异常主机数据: " + reply.AbnormalHostAmount);
    Console.WriteLine("StatService 服务返回主机数据: " + reply.HostAmount);
    Console.WriteLine("StatService 服务返回正常主机数据: " + reply.NormalHostAmount);
    return new Host() { 
        AbnormalHostAmount=reply.AbnormalHostAmount,
        HostAmount=reply.HostAmount,
        NormalHostAmount=reply.NormalHostAmount
    };
}

参考链接

https://www.velotio.com/engineering-blog/grpc-implementation-using-python

https://www.grpc.io/docs/languages/python/quickstart/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.更新pip
  • 2.安装grpc
  • 3.安装gRPC-tool
  • 4.编写.proto文件
  • 5.生成python服务端代码
  • 6.编写服务端代码
    • 1. 引入grpc包与生成的python文件
      • 2. 实现服务端类
      • 7.启动
      • 8.编写客户端代码
        • 1. 安装nuget包
          • 2.编辑csproj文件
            • 3.编码
            • 参考链接
            相关产品与服务
            Serverless HTTP 服务
            Serverless HTTP 服务基于腾讯云 API 网关 和 Web Cloud Function(以下简称“Web Function”)建站云函数(云函数的一种类型)的产品能力,可以支持各种类型的 HTTP 服务开发,实现了 Serverless 与 Web 服务最优雅的结合。用户可以快速构建 Web 原生框架,把本地的 Express、Koa、Nextjs、Nuxtjs 等框架项目快速迁移到云端,同时也支持 Wordpress、Discuz Q 等现有应用模版一键快速创建。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档