.net GRPC服务搭建,跨进程调用。C#应用和Python应用之间的通信。

1.理解GRPC

GRPC本质上是通过谷歌开源的protobuff标准协议实现的传输,和http那种类似,但是他更高效,因为他底层数据是通过二进制传输,比传统的json快很多,通常用于直播间的推流送流。

2.为什么用GRPC

最开始只想解决跨进程通信,用传统的MQ就可以实现,但是GRPC近些年也越来越火了,就试了试。因为他更标准,兼容性更好,可以跨语言跨脚本使用,大家按照他的标准去定义调用就好了。

3.C#应用和Python应用如何通过GRPC互相调用

在这里我C#应用做为GRPC的服务端。Python应用作为客户端去调用。

3.1首先定义标准.proto文件

csharp 复制代码
syntax = "proto3";

option csharp_namespace = "DY_service";

package DY_serviceservice;

// 定义服务
service Calculator {
  rpc Get_result (AddRequest) returns (AddResponse);
}

// 请求消息,包含两个参数
message AddRequest {
  string fullUrl = 1;
  string method = 2;
}

// 响应消息
message AddResponse {
  string result = 1;
}

3.2文件字段解释

  • syntax = "proto3"; // 使用 Protocol Buffers 第3版语法
  • option csharp_namespace = "DY_service"; // 生成的C#代码的命名空间
  • package DY_serviceservice; // 包名(防止命名冲突)
  • Calculator: 服务名称,客户端通过它调用方法。
  • Get_result: 远程方法名,用于计算 。
  • AddRequest: 输入参数类型。
  • AddResponse: 返回结果类型。

3.3搭建C#服务端

3.3.1.创建WinForms项目
3.3.2添加NuGet包
  • 在项目中安装以下NuGet包:
  • Grpc.AspNetCore (包含服务器和客户端库)
  • Google.Protobuf (ProtoBuf消息处理)
  • Grpc.Tools (代码生成工具)
3.3.3添加.proto文件
  • 在项目中添加3.1的proto文件
3.3.4配置.proto文件生成
  • 右键.proto文件 → 属性 → 设置:

  • 生成操作:Protobuf compiler

  • gRPC Stub Classes:Server only

3.3.5实现gRPC服务

创建类CalculatorService.cs:

csharp 复制代码
using DY_service;
using Grpc.Core;
using Microsoft.Extensions.Logging;

namespace DY
{
    public class CalculatorService : Calculator.CalculatorBase
    {
        private readonly ILogger<CalculatorService> _logger;

        public CalculatorService(ILogger<CalculatorService> logger)
        {
            _logger = logger;
        }

        public override async Task<AddResponse> Get_a_bogus(AddRequest request, ServerCallContext context)
        {


            try
            {
                // 直接 await 异步调用,无需 Task.Run
                string result = await Form1.CallJavaScriptFunction(request.FullUrl, request.Method);
                return new AddResponse { Result = result };
            }
            catch (Exception ex)
            {
                // 记录错误并返回空响应(或自定义错误响应)
                Console.WriteLine($"gRPC 调用失败: {ex.Message}");
                return new AddResponse { Result = "ERROR: " + ex.Message };
            }
        }
    }
}

这里的Get_a_bogus方法就是你标准中定义的方法DY_service是标准中的命名空间。然后还有定义的参数,都是和标准文件中一样。

4. 启动gRPC服务器

在Form1的代码中(例如窗体加载事件):

csharp 复制代码
  private IHost _grpcHost;
  private void Form1_Load(object sender, EventArgs e)
  {
      _grpcHost = Host.CreateDefaultBuilder()
 .ConfigureWebHostDefaults(webBuilder =>
 {
     webBuilder.UseStartup<Startup>();
     webBuilder.UseUrls("http://localhost:5000");
     // Program.cs
     webBuilder.ConfigureKestrel(options =>
     {
         options.ListenLocalhost(5000, o => o.Protocols = HttpProtocols.Http2);
     });
 })
 .Build();

      Task.Run(() => _grpcHost.Start()); // 在后台线程启动
  }



  private async void Form1_FormClosed(object sender, FormClosedEventArgs e)
  {


      if (_grpcHost != null)
      {
          try
          {
              // 最多等待 3 秒
              await _grpcHost.StopAsync(TimeSpan.FromSeconds(3));
          }
          catch (Exception ex)
          {
              Debug.WriteLine($"gRPC 服务器停止失败: {ex.Message}");
          }
          finally
          {
              _grpcHost.Dispose();
              _grpcHost = null; // 防止重复释放
          }
      }

      //this.Close(); // 关闭窗口
      //Application.Exit(); // 结束进程
  }

添加Startup.cs类:

csharp 复制代码
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace DY
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }

        public void Configure(IApplicationBuilder app)
        {

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<CalculatorService>();
            });
        }
    }
}

然后运行程序,GRPC服务就启动了。具体的代码意思自己参考官方文档。

5.Python客户端测试代码

  • 安装grpc包
csharp 复制代码
pip install grpcio grpcio-tools

把定义好的 .proto 文件复制到py客户端项目根目录执行如下命令

csharp 复制代码
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. DY__service.proto

只需要把DY_service.proto改成你自己的文件名就行了,然后会生成2个文件。_pb2.py_pb2_grpc.py这2文件中的代码不要改,直接调用就行。

python 复制代码
import grpc
import DY_service_pb2
import DY_service_pb2_grpc

def run():
    channel = grpc.insecure_channel('localhost:5000')
    stub = DY_service_pb2_grpc.CalculatorStub(channel)
    
    response = stub.Get_resut(DY_service_pb2.AddRequest(fullUrl="https://www.dy.com", method="GET"))
    print(f"结果: {response.result}")  # 应该输出 结果

if __name__ == '__main__':
    run()

这样就可以实现基础通信了 直接调用远程方法,总体还是挺方便。

相关推荐
FAREWELL0007531 分钟前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
__lost36 分钟前
Pysides6 Python3.10 Qt 画一个时钟
python·qt
CodeCraft Studio1 小时前
Excel处理控件Spire.XLS系列教程:C# 合并、或取消合并 Excel 单元格
前端·c#·excel
誉鏐1 小时前
PyTorch复现线性模型
人工智能·pytorch·python
weixin_435208162 小时前
通过 Markdown 改进 RAG 文档处理
人工智能·python·算法·自然语言处理·面试·nlp·aigc
东方佑2 小时前
利用Python自动化处理PPT样式与结构:从提取到生成
python·自动化·powerpoint
勘察加熊人3 小时前
forms实现连连看
c#
橘猫云计算机设计3 小时前
基于springboot的考研成绩查询系统(源码+lw+部署文档+讲解),源码可白嫖!
java·spring boot·后端·python·考研·django·毕业设计
hvinsion3 小时前
PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具
c#·powerpoint·ppt·ppt助手·ppt翻页