netcore grpc
一、solution
- 创建空解决方案
> dotnet new sln -n Apricot.Grpc
二、Grpc.Server
- 创建
Apricot.Grpc
类库项目> dotnet new classlib -n Apricot.Grpc# 解决方案添加类库项目> dotnet sln add Apricot.Grpc/Apricot.Grpc.csproj
- 安装依赖
> dotnet add package Grpc.AspNetCore --version 2.66.0> dotnet add package protobuf-net --version 3.2.30
- 创建
Protos
文件夹- 添加
Garner
文件夹,包含增、删、改、查
等操作 - 添加
garner.proto
文件[主文件]
syntax = "proto3"; option csharp_namespace = "Apricot.Grpc";package garner;// google protos import "google/protobuf/empty.proto"; import "google/protobuf/Any.proto";// garner protos import "Protos/Garner/create.proto"; import "Protos/Garner/update.proto"; import "Protos/Garner/get.proto"; import "Protos/Garner/list.proto";// params protos import "Protos/Params/id.proto"; import "Protos/Params/query.proto";// results protos import "Protos/Results/result.proto";// services service Garner{rpc CreateAsync(CreateGarnerRequest) returns(RcpResult);rpc UpdateAsync(UpdateGarnerRequest) returns(RcpResult);rpc RemoveAsync(IdParam) returns(RcpResult);rpc GetAsync(IdParam) returns(GetGarnerResponse);rpc GetListAsync(QueryParam) returns(GetGarnerListResponse); }
- 添加
create.proto
文件syntax = "proto3";option csharp_namespace = "Apricot.Grpc";package garner;// google empty.proto import "google/protobuf/empty.proto";// create request message CreateGarnerRequest{string name = 2;string address = 3; }
- 添加
update.proto
文件syntax = "proto3";option csharp_namespace = "Apricot.Grpc";package garner;// google empty.proto import "google/protobuf/empty.proto";// update request message UpdateGarnerRequest{int64 id = 1;string name = 2;string address = 3;}
- 添加
get.proto
文件syntax = "proto3";option csharp_namespace = "Apricot.Grpc";package garner;// google empty.proto import "google/protobuf/empty.proto";// garner response message GetGarnerResponse{int32 code = 1;string message = 2;bool success = 3;oneof garner{GetGarnerData data =4;} }// garner data message GetGarnerData{int64 id = 1;string name = 2;string address = 3;}
- 添加
list.proto
文件syntax = "proto3";option csharp_namespace = "Apricot.Grpc";package garner;// google empty.proto import "google/protobuf/empty.proto";// garner list response message GetGarnerListResponse{int32 code = 1;string message = 2;bool success = 3;int32 total = 4;repeated GetGarnerListData rows = 5; }// garner list data message GetGarnerListData{int64 id = 1;string name = 2;string address = 3;}
- 添加
- 项目文件添加
.proto
配置<ItemGroup><Protobuf Include="Protos\Results\result.proto" /><Protobuf Include="Protos\Params\query.proto" /><Protobuf Include="Protos\Params\id.proto" /><Protobuf Include="Protos\Garner\get.proto" /><Protobuf Include="Protos\Garner\list.proto" /><Protobuf Include="Protos\Garner\update.proto" /><Protobuf Include="Protos\Garner\create.proto" /><Protobuf Include="Protos\Garner\garner.proto" GrpcServices="Server" /></ItemGroup>
- 编译项目
> dotnet build
- 查看生成类
> dir obj\Debug\net8.0\Protos
- 创建
grpc service
- 创建
GarnerGrpcService
类 - 继承
Garner.GarnerBase
- 重写方法
- 整体代码
public class GarnerGrpcService : Garner.GarnerBase{public override Task<RcpResult> CreateAsync(CreateGarnerRequest request, ServerCallContext context){return Task.FromResult(new RcpResult{Code = StatusCodes.Status200OK,Success = true,});}public override Task<RcpResult> UpdateAsync(UpdateGarnerRequest request, ServerCallContext context){return Task.FromResult(new RcpResult{Code = StatusCodes.Status200OK,Success = true,});}public override Task<RcpResult> RemoveAsync(IdParam request, ServerCallContext context){return Task.FromResult(new RcpResult{Code = StatusCodes.Status200OK,Success = true,});}public override Task<GetGarnerResponse> GetAsync(IdParam request, ServerCallContext context){return Task.FromResult(new GetGarnerResponse{Code = StatusCodes.Status200OK,Success = true,Data = new GetGarnerData{Id = Random.Shared.NextInt64(),Address = "127.0.0.1",Name = "garner"}});}public override Task<GetGarnerListResponse> GetListAsync(QueryParam request, ServerCallContext context){var response = new GetGarnerListResponse{Code = StatusCodes.Status200OK,Success = true,Total = 10,};response.Rows.AddRange(new[]{new GetGarnerListData{Id = Random.Shared.NextInt64(),Address = "127.0.0.1",Name = "garner"},new GetGarnerListData{Id = Random.Shared.NextInt64(),Address = "127.0.0.1",Name = "apricot"}});return Task.FromResult(response);} }
- 创建
三、Grpc.WebApi
- 创建
Apricot.Grpc.WebApi
启动项目> dotnet new web -n Apricot.Grpc.WebApi# 解决方案添加启动项目> dotnet sln add Apricot.Grpc.WebApi/Apricot.Grpc.WebApi.csproj
- 添加项目引用
> dotnet add reference ../Apricot.Grpc/Apricot.Grpc.csproj
- 注入容器、管道
// add grpcbuilder.Services.AddGrpc();// map grpcapp.MapGrpcService<GarnerGrpcService>();
- 协议配置
{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*",// setting http2 protocol"Kestrel": {"EndpointDefaults": {"Protocols": "Http2"}} }
- 支持
Http1/Http2
方法
builder.WebHost.ConfigureKestrel(options =>{// http2options.ListenAnyIP(5132, listenOption =>{listenOption.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;});// http1options.ListenAnyIP(5133, listenOption =>{listenOption.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1;});});
- 支持
- 启动项目
四、apifox 联调 grpc
- 个人团队
- 新建项目
- 类型
grpc
项目
- 类型
- 添加
.proto
-
.proto 文件
- 选择
garner.proto
主文件
- 选择
-
依赖关系目录
- 选择
Protos
文件夹
- 选择
-
错误 & 处理
-
未找到
google protobuf
-
将
google protobuf
拷贝Protos
目录- 目录:%USERPROFILE%.nuget\packages\grpc.tools\2.66.0\build\native\include\google
-
未找到
create.proto
-
将
garner.proto
中import
去掉Protos/
(仅限导入)
-
-
导入成功
-
- 接口测试
create、list
- create
- list
- create