.NET 6.0 の Windowsフォームアプリから、MagicOnion NuGetパッケージを使い、gRPC通信処理を行うサンプルを作成しました。
ソースコードはGitHubで公開しています。
.Net Frameworkで実装されたクライアントサーバシステムを .NET 6.0へ移行するにあたり、MagicOnion Nugetパッケージを使用すると、gRPC通信を使ったクライアントサーバシステムへ簡単に移行できます。
.Net Framework+WCF で実装されたクライアントサーバシステムを、.NET 6.0+WCF Core へ移行し古いHTTTPプロトコルで通信し続けるよりは、HTTP/2のgRPC通信へ移行することが推奨されています。
WCF 開発者に gRPC を推奨する理由 – WCF 開発者向け gRPC | Microsoft Learn
MagicOnionを使うと簡単にクライアント・サーバシステムでgRPC通信を実現できます。
.NETでクライアント・サーバシステムを開発する場合、通信処理はMagicOnionでgRPC通信を実装するのが主流になりそうです。
GitHubのMagicOnion プロジェクトサイトには、MagicOnion開発リポジトリ、インストール手順などがありわかり易いです。
Cysharp/MagicOnion: Unified Realtime/API framework for .NET Platform and Unity (github.com)
MagicOnion サーバ側
ソースコード構成
今回使った Visual Studio プロジェクト テンプレートは、Visual Studio 2022 + .NET 6.0 + ASP.NET Core(空)アプリです。
テンプレートに対して、下記の処理を加えました。
ソースコード変更内容を解説
/WebApplication1.csproj
Grpc.AspNetCore/MagicOnion.Server NuGetパッケージをインストール。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Grpc.AspNetCore" Version="2.51.0" /> <PackageReference Include="MagicOnion.Server" Version="5.1.2" /> </ItemGroup> </Project> |
/Program.cs
MagicOnion.Serverのサービス開始処理を追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using MagicOnion; using MagicOnion.Server; var builder = WebApplication.CreateBuilder(args); builder.Services.AddGrpc(); builder.Services.AddMagicOnion(); var app = builder.Build(); app.MapMagicOnionService(); app.MapGet("/", () => "Hello World!"); app.Run(); |
/Shared/IMyFirstService.cs
MagicOnionを使ってクライアントとサーバを通信するための interfaceを作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using MagicOnion; namespace WebApplication1.Shared { // Defines .NET interface as a Server/Client IDL. // The interface is shared between server and client. public interface IMyFirstService : IService<IMyFirstService> { // The return type must be `UnaryResult<T>` or `UnaryResult`. UnaryResult<int> SumAsync(int x, int y); } } |
/Services/MyFirstService.cs
interfaceに対応するサーバ側の処理を作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using MagicOnion.Server; using MagicOnion; using WebApplication1.Shared; namespace WebApplication1.Services { // Implements RPC service in the server project. // The implementation class must inherit `ServiceBase<IMyFirstService>` and `IMyFirstService` public class MyFirstService : ServiceBase<IMyFirstService>, IMyFirstService { // `UnaryResult<T>` allows the method to be treated as `async` method. public async UnaryResult<int> SumAsync(int x, int y) { Console.WriteLine($"Received:{x}, {y}"); return x + y; } } } |
MagicOnion クライアント側
ソースコード構成
今回使った Visual Studio プロジェクト テンプレートは、Visual Studio 2022 + .NET 6.0 + Windowsフォームアプリです。
テンプレートに対して、下記の処理を加えました。
ソースコード変更内容を解説
/WinFormsApp1.csproj
・MagicOnion.Client NuGetパッケージをインストール。
・MagicOnion サーバ側で作成した interfaceのソースファイルを、リンク参照でSharedフォルダ配下へ追加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net6.0-windows</TargetFramework> <Nullable>enable</Nullable> <UseWindowsForms>true</UseWindowsForms> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <Compile Include="..\..\WebApplication1\WebApplication1\Shared\IMyFirstService.cs" Link="Shared\IMyFirstService.cs" /> </ItemGroup> <ItemGroup> <PackageReference Include="MagicOnion.Client" Version="5.1.2" /> </ItemGroup> <ItemGroup> <Folder Include="Shared\" /> </ItemGroup> </Project> |
/Form1.Designer.cs/Form1.resx
動作を確認する為に最低限の画面を作成。
/Form1.cs
ボタンのクリックイベントに、interfaceを通しサーバ側のSumAsync()メソッドを呼び出す処理を作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using Grpc.Net.Client; using MagicOnion.Client; using WebApplication1.Shared; namespace WinFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { // Connect to the server using gRPC channel. var channel = GrpcChannel.ForAddress("https://localhost:7120"); // Create a proxy to call the server transparently. var client = MagicOnionClient.Create<IMyFirstService>(channel); // Call the server-side method using the proxy. var result = (await client.SumAsync(123, 456)); textBox1.Text = result.ToString(); } } } |
コメント