.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()

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

相关推荐
天才测试猿25 分钟前
常见的Jmeter压测问题
自动化测试·软件测试·python·测试工具·jmeter·职场和发展·压力测试
mortimer26 分钟前
一次与“顽固”外部程序的艰难交锋:subprocess 调用exe踩坑实录
windows·python·ai编程
Eternity_GQM1 小时前
【Word VBA Zotero 引用宏错误分析与改正指南】【解决[21–23]参考文献格式插入超链接问题】
开发语言·c#·word
来自天蝎座的孙孙2 小时前
洛谷P1595讲解(加强版)+错排讲解
python·算法
张子夜 iiii3 小时前
机器学习算法系列专栏:主成分分析(PCA)降维算法(初学者)
人工智能·python·算法·机器学习
跟橙姐学代码4 小时前
学Python像学做人:从基础语法到人生哲理的成长之路
前端·python
Keying,,,,4 小时前
力扣hot100 | 矩阵 | 73. 矩阵置零、54. 螺旋矩阵、48. 旋转图像、240. 搜索二维矩阵 II
python·算法·leetcode·矩阵
桃源学社(接毕设)4 小时前
基于人工智能和物联网融合跌倒监控系统(LW+源码+讲解+部署)
人工智能·python·单片机·yolov8
yunhuibin5 小时前
pycharm2025导入anaconda创建的各个AI环境
人工智能·python
杨荧5 小时前
基于Python的电影评论数据分析系统 Python+Django+Vue.js
大数据·前端·vue.js·python