はじめに
MagicOnion についてはこちらをご覧ください。
MagicOnionにおいて通常のユーザー用RPCとは別に、管理者用コマンドを受け付けたいケースがあります。
(例: static変数にキャッシュした内容のクリア)
そういう場合は管理者用コマンドだけを別ポートから受け付けるようにすると楽です。
実装
Interfaceを定義します。
public interface IAdminService : IService<IAdminService>
{
UnaryResult<Nil> ClearCacheAsync();
}
実装します。このとき、ユーザー用サービスとは別のDLLで作っておくと後で楽です。
public class AdminService : ServiceBase<IAdminService>, IAdminService
{
public UnaryResult<Nil> ClearCacheAsync()
{
// Cache.Clear(); 的なコード
}
}
MagicOnion サーバーの起動時に、どのサービスを使うかを指定することができるので、
ユーザー用ポートでは自身の Assembly を、管理者用ポートでは AdminService を指定します。
※ユーザー用ポートに AdminService を含まないよう注意
public class Program
{
public static async Task Main(string[] args)
{
await MagicOnionHost.CreateDefaultBuilder()
// ユーザー用
.UseMagicOnion(
new[] { typeof(Program).Assembly },
new MagicOnionOptions(true),
new ServerPort("0.0.0.0", 8080, ServerCredentials.Insecure)
)
// 管理者用
.UseMagicOnion(
new[] { typeof(AdminService) },
new MagicOnionOptions(true),
new ServerPort("0.0.0.0", 9999, ServerCredentials.Insecure)
).RunConsoleAsync();
}
}
通信方法
この方法だと管理者用コマンドの呼び出し側でも MagicOnion が必要になるので MicroBatchFramework かなにかでバッチを作っておくと良いでしょう。以下サンプルです。
public class Program : BatchBase
{
static Task Main(string[] args) => new HostBuilder().RunBatchEngineAsync<Program>(args);
[Command("clear_cache")]
public async Task ClearCacheAsync()
{
var channel = new Channel("0.0.0.0:9999", ChannelCredentials.Insecure);
await MagicOnionClient.Create<IAdminService>(channel).ClearCacheAsync();
}