netcore grpc
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 grpc builder.Services.AddGrpc(); // map grpc app.MapGrpcService<GarnerGrpcService>(); - 協議配置
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", // setting http2 protocol "Kestrel": { "EndpointDefaults": { "Protocols": "Http2" } } }- 支持
Http1/Http2方法 [官網]
builder.WebHost.ConfigureKestrel(options => { // http2 options.ListenAnyIP(5132, listenOption => { listenOption.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2; }); // http1 options.ListenAnyIP(5133, listenOption => { listenOption.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1; }); }); - 支持
- 啟動項目
> dotnet run
四、Grpc.Client
- 創建
Apricot.Grpc.Client項目> dotnet new web -n Apricot.Grpc.Client # 解決方案添加客戶端 > dotnet sln add Apricot.Grpc.WebApi/Apricot.Grpc.Client.csproj - 安裝依賴
> dotnet add package Grpc.Net.Client --version 2.66.0 > dotnet add package Google.Protobuf --version 3.28.2 > dotnet add package Grpc.Tools --version 2.67.0 > dotnet add package Grpc.Net.ClientFactory --version 2.66.0 > dotnet add package protobuf-net --version 3.2.30 - 復制
Protos文件夾至Apricot.Grpc.Client項目 - 添加
.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="Client" /> </ItemGroup> - 編譯項目
> dotnet build - 注入容器
// add client builder.Services.AddGrpcClient<Garner.GarnerClient>(option => { option.Address = new Uri("http://localhost:5132"); }) - 服務調用
app.Map("/grpc", (HttpContext context) => { var client = context.RequestServices.GetRequiredService<Garner.GarnerClient>(); var data = client.GetListAsync(new QueryParam { PageIdex = 1, PageSize = 10 }); context.Response.WriteAsJsonAsync(data); });
五、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

- 錯誤 & 處理
- 錯誤:
Received RST_STREAM with code 2 triggered by internal client error: Protocol error - 處理:將請求地址改成
Http2協議端口。
- 錯誤:
- create
如有幫助,歡迎轉載,轉載請注明原文鏈接:http://www.rzrgm.cn/study10000/p/18476165

浙公網安備 33010602011771號