.NET 6 使用 MagicOnion 實現 gRPC

来源:https://www.cnblogs.com/Honesty-is-the-best-policy/archive/2022/12/07/16963298.html
-Advertisement-
Play Games

.NET 6 使用 MagicOnion MagicOnion開源地址:https://github.com/Cysharp/MagicOnion 什麼是MagicOnion? MagicOnion 是用於 .NET 平臺的現代 RPC 框架,它提供雙向實時通信(如SignalR和Socket.io ...


.NET 6 使用 MagicOnion

MagicOnion開源地址:https://github.com/Cysharp/MagicOnion

什麼是MagicOnion?

MagicOnion 是用於 .NET 平臺的現代 RPC 框架,它提供雙向實時通信(如SignalRSocket.io)和 RPC 機制(如 WCF 和基於 Web 的 API)。

此框架基於gRPC,它是用於 HTTP/2 的快速緊湊的二進位網路傳輸。但是,與普通 gRPC 不同,它將 C# 介面視為協議架構,從而在沒有 C# 項目(協議緩衝區 IDL)的情況下實現無縫代碼共用。.proto

MagicOnion快速入門 (創建伺服器端項目)

首先,您需要從 Visual Studio 或 .NET CLI 工具中創建gRPC Service項目。MagicOnion Server 建立在 ASP.NET Core 和 gRPC 之上,因此伺服器項目必須是 ASP.NET Core 項目。

創建gRPC伺服器微軟文檔:在 ASP.NET Core 中創建 .NET Core gRPC 客戶端和伺服器 | Microsoft Learn

創建項目時,它包含 protos 文件夾,這個在 MagicOnion 中不需要所以可以刪除。

將 NuGet 包添加到項目。MagicOnion.Server 當然也可以用開發者 PowerShell 命令安裝命令如下:

dotnet add package MagicOnion.Server

因為我們用的是 .NET 6 框架沒有 Startup.cs 文件,所以我們在 Program.cs 中添加

builder.Services.AddMagicOnion();

app.UseEndpoints調用方法重寫如下。

app.UseEndpoints(endpoints =>
{
    endpoints.MapMagicOnionService();

    endpoints.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
    });
});

完整的 Program.cs 文件如下:

using MyFirstMagicOnionServer.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

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

var app = builder.Build();

// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();

app.UseRouting() // 添加 UseRouting 

app.UseEndpoints(endpoints =>
{
    endpoints.MapMagicOnionService();

    app.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
    });
});

app.Run();

ps:這邊有個坑,運行之後會報一個錯誤:EndpointRoutingMiddleware matches endpoints setup by EndpointMiddleware and so must be added to the request execution pipeline before EndpointMiddleware. Please add EndpointRoutingMiddleware by calling 'IApplicationBuilder.UseRouting' inside the call to 'Configure(...)' in the application startup code.

意思就是說要在app.UseEndpoints()方法前面加上app.UseRouting() 方法

在RPC服務端項目上使用MagicOnion

MagicOnion提供類似Web API的RPC服務和用於實時通信的StreamingHub。本節實現類似於 Web API 的 RPC 服務。添加要在伺服器和客戶端之間共用的介面(命名空間應與項目匹配)。

創建共用庫(共用庫,客戶端服務端都要有)

創建一個 Shared 文件夾 裡面再創建一個介面文件 IMyFirstService

using MagicOnion;

namespace MyFirstMagicOnionServer.Shared
{
    // 將 .NET 介面定義為 Server/Client IDL.
    // 這介面在伺服器和客戶端之間共用
    public interface IMyFirstService : IService<IMyFirstService>
    {
        // 該返回的類型必須是 UnaryResult<T>
        UnaryResult<int> SumAsync (int x,int y);
    }
}

添加實現介面的類(服務端實現)

創建一個 Service 文件夾裡面再創建一個實現類 MyFirstMagicOnionServer

using MagicOnion;
using MagicOnion.Server;
using MyFirstMagicOnionServer.Shared;

namespace MyFirstMagicOnionServer.Services
{
    public class MyFirstService : ServiceBase<IMyFirstService>, IMyFirstService
    {
        public async UnaryResult<int> SumAsync(int x, int y)
        {
            Console.WriteLine($"Received:{x}, {y}");
            await Task.Run(() => true);
            return x + y;
        }
    }
}

客戶端:在MagicOnion上調用服務

創建控制台應用程式項目並將 NuGet 包添加到該項目。MagicOnion.Client

與客戶端共用介面。以某種方式共用介面定義,例如文件鏈接、共用庫或複製和粘貼。IMyFirstService 我這邊採用複製粘貼的模式把 MagicOnion 服務端上的shared文件夾複製到控制台程式(這邊記得修改IMyFirstService 的命名空間)

在客戶端代碼中,共用介面上的 Createclient 代理並透明地調用服務。MagicOnionClient

using Grpc.Net.Client;
using MagicOnion.Client;
using MyFirstMagicOnionClient.Shared;

// 引用 gRPC 的 channel 連接到伺服器。
var channel = GrpcChannel.ForAddress("http://localhost:33559"); // 服務端運行的介面地址

// 創建一個代理來透明的調用伺服器
IMyFirstService client = MagicOnionClient.Create<IMyFirstService>(channel);

// 使用代理調用服務端的方法
var result = await client.SumAsync(123, 456);

Console.WriteLine($"Result: {result}");

介紹 MagicOnion 的四個 NuGet 包

  • MagicOnion.Server 包來實現伺服器。您需要安裝此軟體包才能在伺服器上實現服務。
  • MagicOnion.Client 包來實現客戶端。若要實現 WPF 和 Xamarin 等客戶端,需要安裝此包。
  • MagicOnion.Abstractions 該包提供伺服器和客戶端常用的介面和屬性。若要創建在伺服器和客戶端之間共用的類庫項目,需要安裝此包。
  • MagicOnion 包是元包,用於實現伺服器和客戶端的角色。 若要實現伺服器到伺服器的通信(如微服務),可以是伺服器也可以是客戶端,我們建議安裝此包。

WebApi 使用 MagicOnion

  1. 創建一個 WebApi 項目(名字自取)
  2. 和上面控制台伺服器一樣添加 Nuget 包 MagicOnion.Server
  3. 在 Program.cs 裡面添加:
builder.Services.AddGrpc();
builder.Services.AddMagicOnion();

app.UseRouting();  // 調用UseRouting()

app.UseEndpoints(endpoints =>
{
    endpoints.MapMagicOnionService();

    endpoints.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
    });
});

附帶完整的 Program.cs

using MagicOnion;
using MagicOnion.Server;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

#region 添加的 MagicOnion
builder.Services.AddGrpc();
builder.Services.AddMagicOnion();
#endregion

var app = builder.Build();


// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseRouting();  // 調用UseRouting()

app.UseAuthorization();

// 添加的
app.UseEndpoints(endpoints =>
{
    endpoints.MapMagicOnionService();

    endpoints.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
    });
});

app.MapControllers();

app.Run();

  1. 創建介面和實現類

創建介面:和上面gRPC一樣 創建一個 Shared 文件夾,裡面創建 IMyFirstService 介面文件

using MagicOnion;

namespace MagicOnionWebApi.Shared
{
    // 將 .NET 介面定義為 Server/Client IDL.
    // 這介面在伺服器和客戶端之間共用
    public interface IMyFirstService : IService<IMyFirstService>
    {
        // 該返回的類型必須是 UnaryResult<T>
        UnaryResult<int> SumAsync (int x,int y);
    }
}

實現介面:也和上面一樣創建一個 Service 文件夾裡面再創建一個實現類 MyFirstMagicOnionServer

public class MyFirstService : ServiceBase<IMyFirstService>, IMyFirstService
{
    public async UnaryResult<int> SumAsync(int x, int y)
    {
        Console.WriteLine("服務端接受到請求");
        Console.WriteLine($"Received:{x}, {y}");
        await Task.Run(() => true);
        return x + y;
	}
}
  1. 客戶端調用:

用上面創建的 MagicOnion 客戶端項目改一下請求地址就好了:

// 修改服務端的介面地址
var channel = GrpcChannel.ForAddress("https://localhost:7109"); // 服務端運行的介面地址

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 用戶空間和內核態空間 1.1 為什麼要區分用戶和內核 伺服器大多都採用 Linux 系統,這裡我們以 Linux 為例來講解: ubuntu 和 Centos 都是 Linux 的發行版,發行版可以看成對 linux 包了一層殼,任何 Linux 發行版,其系統內核都是 Linux 。我們的應 ...
  • 作者:賈世聞 我們在開發應用後端系統的時候經常要和各種資料庫、緩存等資源打交道。這一期,我們聊聊如何訪問redis 並將資源池化。 在一個應用後端程式訪問redis主要要做的工作有兩個,單例和池化。 在後端應用集成redis,我們主要用到以下幾個crate:​ ​once_cell​​​、​ ​re ...
  • 1. 版本問題 1.1. Activiti版本 7.1.0-M6是最後一個支持JDK1.8的版本,此後的版本都要求JDK11以上 目前,Activiti最新版本是7.6.0,它是用JDK11編譯的,因此要想使用最新版7.6.0必須升級JDK版本,不能再用1.8 同時,7.6.0依賴的SpringBo ...
  • aliases: [JAVA Lambda] tags : " #Java " summary: [如何使用函數式編程寫出優雅高效的JAVA代碼] author : [yaenli] date : [2022-11-10] 1 簡介 簡潔的代碼就能處理大型數據集合,讓複雜的集合處理演算法高效的運行在多 ...
  • "Writing in C or C++ is like running a chain saw with all the safety guards removed. " - Bob Gray “用C或C++寫代碼就像是在揮舞一把卸掉所有安全防護裝置的鏈鋸。” —— 鮑勃·格雷 0x00 大綱 0 ...
  • keys命令的用法: keys pattern 查找符合正則匹配的key的列表。掃描對象是Redis服務中所有的key,想想都很慢對不對? 同時執行keys命令的同時,Redis進程將被阻塞,無法執行其他命令,假如超過了哨兵的down-after-milliseconds配置,還會進行主從切換,切換 ...
  • 原文鏈接 [https://www.cnblogs.com/densen2014/p/16964858.html] 在Blazor項目嵌入 pdf.js 時不能正確顯示中文,瀏覽器F12顯示如下錯誤 錯誤 l10n.js /web/locale/locale.properties not found ...
  • 當我們編寫了自己的C#程式,有程式自定義的文件類型時,通常希望它滿足以下需求:雙擊自定義文件打開自定義程式、自定義文件有著自己的圖標 此時,在網上檢索可以發現,大多數回答是使用Microsoft.Win32下的CreateSubKey(String)函數,但是很不幸,Win10的註冊表項受訪問控制列... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...