NETCORE - Grpc 通信

NETCORE - Grpc 通信

项目框架:Net6 

 

  一. 服务端项目 

1. 创建 ASP.NET Core gRPC 框架项目:NETCORE.GrpcService

安装插件包

Grpc.AspNetCore.Server.Reflection
Grpc.Tools

 

 

 

2. 注意 appsettings.json 文件中的配置,(webapi中不能这么配置,需开启http2 )

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}

 

3. 在Protos下增加新的 文件 sence.proto

syntax = "proto3";

option csharp_namespace = "RailAssist.Grpc";

import "google/protobuf/wrappers.proto";

package sence;

// The greeting service definition.
service senceInfoer {
  // Sends a greeting
  rpc GetSenceInfo (SenceInfoRequest) returns (SenceInfoReply);
}

// The request message containing the user's name.
message SenceInfoRequest {
  int32 fileId = 1;
  //repeated string arr= 2;//list<string>类型
}

message NodeInfo {
  int64 Id = 1;
  google.protobuf.StringValue Name= 2;
  google.protobuf.Int64Value ParentId = 3;
}
 
message PropSetInfo {
  int64 Id = 1;
  google.protobuf.StringValue  Name= 2;
  int64 nodeId=3;
}

message PropInfo {
     int64 Id = 1;
     google.protobuf.StringValue  Name= 2;
    google.protobuf.StringValue   Type=3;
    google.protobuf.StringValue   Value=4;
    google.protobuf.StringValue   Unit=5;
      int64 PsetId=6;
}
 
// The response message containing the greetings.
message SenceInfoReply {
 repeated NodeInfo nodeArr = 1;
 repeated PropSetInfo propSetArr = 2; 
 repeated PropInfo propArr = 3;
}

 

 4. 在Services 下 增加新的服务 SenceService.cs

using Grpc.Core;
using Rail.Service.TestPlatform.IService;
using RailAssist.Grpc;

namespace RailAssist.Grpc.Services;

public class SenceService : senceInfoer.senceInfoerBase
{
    private readonly ILogger<SenceService> _logger;
    private ISencesRepository iSencesRepository;
    public SenceService(ILogger<SenceService> logger, ISencesRepository _iSencesRepository)
    {
        _logger = logger;
        iSencesRepository = _iSencesRepository;
    }

    public override async Task<SenceInfoReply> GetSenceInfo(SenceInfoRequest request, ServerCallContext context)
    {
        //// 创建 NodeInfo 对象的列表
        //var nodeInfoList = new List<NodeInfo>
        //{
        //    new NodeInfo { Id = 1, Name = "NodeA" },
        //    new NodeInfo { Id = 2, Name = "NodeB" },
        //    // ... 添加更多 NodeInfo 对象 ...
        //};

        //// 创建 SenceInfoReply 实例并设置 node_info_arr 字段
        //var reply = new SenceInfoReply
        //{
        //    NodeArr = { nodeInfoList } // 使用集合初始化器添加元素到 repeated 字段
        //};

        //// 返回 Task,因为 gRPC 方法是异步的
        //return Task.FromResult(reply);


        var resData = await iSencesRepository.GetSenceInfo(request.FileId);

        var nodeInfoList = from n in resData.nodeArr select new NodeInfo { Id = n.Id, Name = n.Name, ParentId = n.ParentId };
        var propSetInfoList = from n in resData.propSetArr select new PropSetInfo { Id = n.Id, Name = n.Name, NodeId = n.nodeId };
        var propInfoList = from n in resData.propArr select new PropInfo { Id = n.Id, Name = n.Name, PsetId = n.PsetId, Type = n.Type, Unit = n.Unit, Value = n.Value };

        var reply = new SenceInfoReply
        {
            NodeArr = { nodeInfoList },
            PropSetArr = { propSetInfoList },
            PropArr = { propInfoList }
        };

        //return Task.FromResult(reply);
        return reply;

    }
}

 

 5. 在Program.cs 中注入服务

app.MapGrpcService<SenceService>();

 

6. 注意数据量大小限制的配置,在Program.cs 中

builder.Services.AddGrpc(options =>
{
    options.MaxReceiveMessageSize = int.MaxValue; // 设置接收消息的最大尺寸
    options.MaxSendMessageSize = int.MaxValue;// 来限制发送消息的最大尺寸
});

 

 

 

6. 项目启动后地址:https://localhost:7180

 

  二. Postman测试

 

 

上传

 

 

 

 

 

 

  三. 发布项目 - 本地 

发布项目后,不可用IIS,不支持。

可在发布文件夹内,双击.exe文件启动。

 

或执行命令:

dotnet GrpcTempServer.dll cc --urls "http://0.0.0.0:5000"

 

 

  四. 发布项目 - Docker

发布Docker时,使用Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
MAINTAINER lihongyuan
LABEL description="this is a test website"
LABEL version="1.0"
# ENV TimeZone=Asia/Shanghai
# RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
WORKDIR /app
COPY . .
EXPOSE 80
ENTRYPOINT ["dotnet", "GrpcTempServer.dll"] 

 

创建容器:

docker run --name mydemo -d -p 14421:80 imagedemo

 

 

  五. webApi 项目整合 Grpc 框架

 

 1. 增加配置项 

在文件 appsettings.json 中,webapi中不能这么配置,想其他办法,需为webapi开启http2

    "AllowedHosts": "*",
    "Kestrel": {
        "EndpointDefaults": {
            "Protocols": "Http2"
        }
    }

 

 

2. 安装插件包

 

3. 定义Grpc 服务

在项目中创建gRPC服务的.proto文件。例如,增加文件夹 Protos,创建一个名为greet.proto的文件,并定义你的服务和方法。

 

syntax = "proto3";

option csharp_namespace = "RailAssist.Grpc";

package greet;

// 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;
}

 

 

4. 生成 Grpc 代码

使用Grpc.Tools包中的工具将.proto文件编译成C#代码。在你的项目文件中添加以下项以启用代码生成,打开项目的 .csproj 文件

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

 

 这将会自动将.proto文件编译成C#代码,并放置在指定的输出目录中(通常是obj\Debug\net6.0\Protos)。

 

5. 实现 Grpc 服务

创建 GrpcService 文件夹,创建 GreeterService.cs 文件

using Grpc.Core;
using RailAssist.Grpc;

namespace RailAssist.Controllers.GrpcService;

public class GreeterService : Greeter.GreeterBase
{
    private readonly ILogger<GreeterService> _logger;
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
    {
        return Task.FromResult(new HelloReply
        {
            Message = "Hello " + request.Name
        });
    }
}

 

 

6. 在 Program.cs 中配置gRPC服务和中间件

builder.Services.AddGrpc();
app.MapGrpcService<GreeterService>();

 

 

7. 测试

 

 

  六. 客户端项目

1. 创建控制台项目:NETCORE.GrpcCli 然后把服务端的这个文件夹整体拿过来放在客户端下面ent

安装如下三个Nuget包

Google.Protobuf
Grpc.Net.Client
Grpc.Tools

 

2. 客户端项目修改

  把服务端的 Protos 文件夹 复制到客户端项目下面(这个意思就是,他们有共同的协议,就互通了)

   双击客户端项目名称文件,即 NETCORE.GrpcClient.csproj 文件,调整配置项

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>

 

 

3. 接口调用

  在客户端中 Program.cs 编写方法调用 服务端接口,注意接口使用服务端接口

// See https://aka.ms/new-console-template for more information
using Grpc.Net.Client;
using NETCORE.GrpcService;

Console.WriteLine("Hello, World!");

string url = "https://localhost:7180";   //https
using (var channel = GrpcChannel.ForAddress(url))
{
    var client = new Greeter.GreeterClient(channel);
    var reply = client.SayHello(new HelloRequest()
    {
        Name = "故里2130"
    });
    Console.WriteLine($"结果:message:{reply.Message}");
}
Console.ReadKey();
//AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);  //http调用
//string url = "http://localhost:5000";
//using (var channel = GrpcChannel.ForAddress(url))
//{
//    var client = new Greeter.GreeterClient(channel);
//    var reply = client.SayHello(new HelloRequest()
//    {
//        Name = "故里2130"
//    });
//    Console.WriteLine($"结果:message:{reply.Message}");
//}
//Console.ReadKey();

 

 

4. 测试

在启动服务端的前提下,启动客户端,接口调用完成,输出结果。

 

 

 

 

 

 

 

 

这样就完成了简单的使用过程,和webapi的效果差不多。但是它的速度远远大于webapi

 

 

 

 

 

 

引用:https://www.jb51.net/aspnet/288820mey.htm

 

posted @ 2023-09-05 15:17  无心々菜  阅读(19)  评论(0编辑  收藏  举报