首頁

目前文章總數:157 篇

  

最後更新:2024年 12月 07日

0056. .Net Core WebSite網站與 gRPC Server整合架構運行的方法

日期:2023年 11月 26日

標籤: C# Asp.net Core Web MVC Web gRPC CentOS Postman

摘要:C# 學習筆記


應用所需:1. Visual Studio 2022 以上,支援.net Core6
      2. Postman 測試gRPC是否成功
範例檔案:範例檔案
解決問題:1. .Net Core WebSite與gRPC Server整合一起,當網站架構與gRPC相依時,可在同個Server下,避免雙Server造成網路通信的資源浪費
基本介紹:本篇分為二大部分。
第一部分:新建專案與配置
第二部分:PostMan驗證結果






第一部分:新建專案與配置

Step 1:新建Web專案

這邊建立一個Asp.net Core Web (MVC)的應用程式


Step 2:Nuget安裝gRPC

開啟Nuget,只要安裝Grpc.AspNetCore 套件即可
目前套件已經整合80%了,不需要下載protoc.exe 安裝,後續建置時會自動生成.proto 對應的.cs基本代碼

Grpc.AspNetCore 




Step 3:創建proto檔案 - 1

proto檔案是gRPC通訊緩衝協議的重要核心,是Google開發的一種輕量且高效的數據序列化格式
Protocol Buffers 的定義文件,用於描述 gRPC 服務端和客戶端之間通信的協定。


proto定義:

定義 說明
1. 數據結構定義 包括消息類型和其字段。這些數據結構用 Protobuf 的語法描述,它支持基本數據類型(例如整數、字符串等)以及複合數據結構。
2. 消息定義 定義在 gRPC 通信中使用的消息格式。每個消息類型都有一個唯一的名稱,並包含一組字段,每個字段都有一個標識符(例如 name、id、email)以及其類型。
3. 服務定義 包含了描述 gRPC 服務的定義。這包括服務的名稱、可以呼叫的方法以及每個方法的輸入和輸出消息類型。


依序建議資料夾與Protocol Buffers 檔案


Step 4:創建proto檔案 - 2

mygrpctest.proto 代碼內容:

// 1. 這是proto 通訊串流使用的,安裝套件提供預設 proto3
syntax = "proto3";

// 2. 命名空間,可以同專案
option csharp_namespace = "NetCoreMvcWebSiteWithGrpcExample";

// 3. 同檔案名稱
package mygrpctest;

// 4. 會對應到C#中業務邏輯的 Service的主類別名稱 
service MyGrpcTester {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

// 5. 請求攜帶的參數
message HelloRequest {
  string name = 1;
}

// 6. 當被請求後返回內容
message HelloReply {
  string message = 1;
}



Step 5:建立邏輯檔案 - 1

接著依序新建立C#的邏輯處理類.cs檔案


Step 6:建立邏輯檔案 - 2

MyGrpcTesterService.cs 代碼內容

using Grpc.Core;
using NetCoreMvcWebSiteWithGrpcExample;

namespace NetCoreMvcWebSiteWithGrpcExample.Services
{
    //1. 主類名稱 MyGrpcTesterService 其中MyGrpcTester與 mygrpctest.proto 配置的要相同
    public class MyGrpcTesterService : MyGrpcTester.MyGrpcTesterBase
    {
        private readonly ILogger<MyGrpcTesterService> _logger;
        public MyGrpcTesterService(ILogger<MyGrpcTesterService> logger)
        {
            _logger = logger;
        }

        //2. 測試代碼,HTTP/2 接口名稱 SayHello ,如果有人帶 HelloRequest 的請求參數
        //   我們返回 HelloReply 的返回內容
        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}



Step 7:調整csproj專案檔配置方法1 - 1

在MSDN微軟的官方教學,需要手動對.csproj設定,到專案下,打開.csproj配置
未處理這段前,代碼會建置失敗,會找不到 MyGrpcTester.MyGrpcTesterBase


Step 8:調整csproj專案檔配置方法1 - 2

將.proto的檔案路徑,配置到ItemGroup中,本範例是Web + gRPC作為服務器端,所以添加參數:GrpcServices=”Server”

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


保存後,代碼就可以建置成功


Step 9:調整csproj專案檔配置方法2 - 1

更便捷、安全的方法可以從專案 -> 滑鼠右鍵 -> 加入 -> 服務參考


Step 10:調整csproj專案檔配置方法2 - 2

選擇gRPC配置


Step 11:調整csproj專案檔配置方法2 - 3

選擇我們的.proto檔案,並且決定是伺服器(本篇只用到伺服器功能)
即可完成自動生成proto檔案對應的Service代碼,同Step7,Step8 的成果


Step 12:調整啟動配置

到專案的啟動配置 program.cs 添加以下代碼,如果未配置會導致gRPC無法正常訪問該站台
透過檢查HttpRequest的Header是否有 application/grpc 來判斷是否為gRPC請求

using NetCoreMvcWebSiteWithGrpcExample.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// 1. 建立Grpc通信
builder.Services.AddGrpc();

var app = builder.Build();

//2. 加入設定檔的Service ※建議在中間件 middleware觸發前
app.MapGrpcService<MyGrpcTesterService>();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

//3-1. 檢查是否為GRPC的請求,是的話則不進行 HTTPS 重定向
app.Use(async (context, next) =>
{
    if (context.Request.Headers.ContainsKey("content-type") &&
        context.Request.Headers["content-type"].ToString().StartsWith("application/grpc", StringComparison.OrdinalIgnoreCase)
        )
    {
        // 如果不是 gRPC 請求,應用 HTTPS 重定向
        context.Request.Scheme = "https";
        await next();
    }
    else
    {
        await next();
    }
});

//3-2. 如果不設定3-1. 這段會讓GRPC無法通信,因為GRPC走的是HTTP/2 協議
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
  





第二部分:PostMan驗證結果

Step 1:執行程式

我們啟動專案,可以利用Debug模式啟動


Step 2:PostMan測試 - 1

接著開啟Postman 選擇gRPC的測試


Step 3:PostMan測試 - 2

這邊的端口用Http做測試,因為我們目前用Debug測試未使用Https的協議證書


Step 4:PostMan測試 - 3

選擇匯入 proto 檔案


Step 5:PostMan測試 - 4

選擇我們專案檔中的 .proto 檔案,並且匯入



Step 6:PostMan測試 - 5

接著可以看到Postman可以選擇對應的呼叫接口 SayHello


Step 7:PostMan測試 - 6

選擇Invoke後,出現失敗,是因為Postman的測試需要將通訊協議改為 grpc://


Step 8:PostMan測試 - 完成

改成 grpc:// 即可正常呼叫,web 與 gRPC 架在同個伺服器即完成
因 web 與 gRPC 在同個Server下,如果內部Client端交用gRPC,可以不用透過網路資源傳遞。內部邏輯層可完成請求。