C#
docker
gRPC
.NETCore
MagicOnion

Docker を利用して MagicOnion & .Net Core の開発環境を整える

はじめに

Docker を利用して MagicOnion & .Net Core の開発環境を整えます。

2018/12/14 に MagicOnion のバージョンが 2.0.3 になりました。
基本的にこの記事の通りで動作しますが、GitHub へのリンクは古いバージョンのものです。

前提条件

  • Visual Studio がインストールされていること
  • .NET Core 2.2 SDK がインストールされていること (2018/12/15 追記)
  • Docker がインストールされていること

サービス定義の作成

サービス定義プロジェクトの作成

サービス定義プロジェクトを .NET Standard クラスライブラリ で作成します。

NuGet パッケージのインストール (サービス定義)

MagicOnion をインストールします。

Install-Package MagicOnion

インターフェースの作成

public interface IMyFirstService : IService<IMyFirstService>
{
    UnaryResult<int> SumAsync(int x, int y);
}

commit:サービス定義の作成

サーバーの作成

サーバープロジェクトの作成

サーバープロジェクトを .NET Core コンソールアプリ で作成します。

NuGet パッケージのインストール (サーバー)

MagicOnion をインストールします。

Install-Package MagicOnion

参照の追加 (サーバー)

サービス定義プロジェクト を参照に追加します。

.csproj
<ItemGroup>
  <ProjectReference Include="..\MagicOnionInDocker.ServiceDefinition\MagicOnionInDocker.ServiceDefinition.csproj" />
</ItemGroup>

サービスの作成

public class MyFirstService : ServiceBase<IMyFirstService>, IMyFirstService
{
    public async UnaryResult<int> SumAsync(int x, int y)
    {
        Logger.Debug($"Received:{x}, {y}");

        return x + y;
    }
}

サーバーの起動

class Program
{
    static void Main(string[] args)
    {
        GrpcEnvironment.SetLogger(new Grpc.Core.Logging.ConsoleLogger());

        var service = MagicOnionEngine.BuildServerServiceDefinition(isReturnExceptionStackTraceInErrorDetail: true);

        var server = new global::Grpc.Core.Server
        {
            Services = { service },
            Ports = { new ServerPort("localhost", 12345, ServerCredentials.Insecure) }
        };

        // launch gRPC Server.
        server.Start();

        Console.ReadLine();
    }
}

commit:サーバーの作成

クライアントの作成

今回は単純なクライアントではなく、ASP.NET Core を利用した Swagger をクライアントとして利用します。

クライアントプロジェクトの作成

クライアントプロジェクトを ASP.NET Core Web アプリケーション で作成します。

NuGet パッケージのインストール (クライアント)

MagicOnionMagicOnion.HttpGateway をインストールします。

Install-Package MagicOnion
Install-Package MagicOnion.HttpGateway

参照の追加 (クライアント)

サービス定義プロジェクト と サーバープロジェクト を参照に追加します。

.csproj
<ItemGroup>
  <ProjectReference Include="..\MagicOnionInDocker.Server\MagicOnionInDocker.Server.csproj" />
  <ProjectReference Include="..\MagicOnionInDocker.ServiceDefinition\MagicOnionInDocker.ServiceDefinition.csproj" />
</ItemGroup>

クライアントの起動

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        var service = MagicOnionEngine.BuildServerServiceDefinition(new Assembly[] { Assembly.GetAssembly(typeof(MyFirstService)) }, new MagicOnionOptions(true)
        {
            MagicOnionLogger = new MagicOnionLogToGrpcLogger()
        });
        // Add MagicOnionServiceDefinition for reference from Startup.
        services.Add(new ServiceDescriptor(typeof(MagicOnionServiceDefinition), service));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        var magicOnion = app.ApplicationServices.GetService<MagicOnionServiceDefinition>();
        var xmlPath = Path.Combine(AppContext.BaseDirectory, "MagicOnionInDocker.ServiceDefinition.xml");
        app.UseMagicOnionSwagger(magicOnion.MethodHandlers, new MagicOnion.HttpGateway.Swagger.SwaggerOptions("MagicOnionInDocker.Server", "Swagger Integration Test", "/")
        {
            XmlDocumentPath = xmlPath
        });
        app.UseMagicOnionHttpGateway(magicOnion.MethodHandlers, new Channel("localhost:12345", ChannelCredentials.Insecure));
    }
}

ここまでで一通り動作するので、マルチスタートアッププロジェクトでサーバーとクライアントを実行し動作確認しておくといいです。

commit:クライアントの作成

コンテナー オーケストレーター サポートの追加

今回は Docker Compose を利用します。
サーバープロジェクト と クライアントプロジェクト で Visual Studio でプロジェクトを右クリックから コンテナー オーケストレーター サポート を追加します。
docker-compose.ymlDockerfile は自動生成されたものから変更する必要はありません。

commit:コンテナー オーケストレーター サポートの追加

host の変更

Docker で動作するように host を変更します。

サーバープロジェクト

Program.cs
var server = new global::Grpc.Core.Server
{
    Services = { service },
    Ports = { new ServerPort("0.0.0.0", 12345, ServerCredentials.Insecure) }
};

クライアントプロジェクト

Startup.cs
app.UseMagicOnionHttpGateway(magicOnion.MethodHandlers, new Channel("magiconionindocker.server", 12345, ChannelCredentials.Insecure));

commit:host の変更

TODO

  • host / port の設定ファイル化