項目結構
開始Orleans之前,我們都知道Orleans主要可以分為倆部分,Host和Client。
所以我們可以創建如下的項目結構:
IGrain 一個包含Grain接口的庫(.NET Standard 2.1)
Grain 一個包含Grain類的庫(.NET Standard 2.1)
Host 一個控制台應用程序,用來托管我們的Silo(.NET Core 3.1)
Client 一個控制台應用程序,用來做我們的Orleans客戶端(.NET Core 3.1)
Orleans引用
NuGet咋用不用我再贅述了吧。
IGrain
Microsoft.Orleans.Core.Abstractions(3.0.1)
Microsoft.Orleans.CodeGenerator.MSBuild(3.0.1)
Grain
Microsoft.Orleans.Core.Abstractions(3.0.1)
Microsoft.Orleans.CodeGenerator.MSBuild(3.0.1)
Microsoft.Extensions.Logging.Abstractions(3.1.0)//用於日志記錄
Host
Microsoft.Orleans.Server(3.0.1)
Microsoft.Extensions.Logging.Console(3.1.0)//用於控制台信息打印
Client
Microsoft.Orleans.Client(3.0.1)
Microsoft.Extensions.Logging.Console(3.1.0)//用於控制台信息打印
定義Grain接口
在IGrain項目中,添加一個IHello.cs
代碼文件,並在其中定義以下IHello接口:
using IGrain;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace Grain
{
public class HelloGrain : Orleans.Grain, IHello
{
private readonly ILogger logger;
public HelloGrain(ILogger<HelloGrain> logger)
{
this.logger = logger;
}
Task<string> IHello.SayHello(string greeting)
{
logger.LogInformation($"\n 收到SayHello消息: greeting = '{greeting}'");
return Task.FromResult($"\n Client said: '{greeting}', so HelloGrain says: Hello!");
}
}
}
創建Silo
在這一步,我們修改Host的Program.cs
以初始化托管和運行我們的Grain服務器-Silo。在這里我們用代碼來控制群集和連接,實際應用的配置可以在Orleans文檔的“ 本地開發配置”頁面中找到更多的信息。現在的例子只是運行具有單個Silo的集群。
using Grain;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace Host
{
class Program
{
static int Main(string[] args)
{
Console.WriteLine("Hello World!");
return RunMainAsync().Result;
}
private static async Task<int> RunMainAsync()
{
try
{
var host = await StartSilo();
Console.WriteLine("\n\n 按回車鍵停止 \n\n");
Console.ReadLine();
await host.StopAsync();
return 0;
}
catch(Exception ex)
{
Console.WriteLine(ex);
return 1;
}
}
private static async Task<ISiloHost> StartSilo()
{
//定義群集配置
var builder = new SiloHostBuilder()
.UseLocalhostClustering()//配置Silo只使用開發集群,並監聽本地主機
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";//獲取或設置群集標識。這在Orleans 2.0名稱之前曾被稱為DeploymentId。
options.ServiceId = "OrleansBasics";//獲取或設置此服務的唯一標識符,該標識符應在部署和重新部署后繼續存在,其中Orleans.Configuration.ClusterOptions.ClusterId可能不存在。
})
.ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences())
.ConfigureLogging(logging => logging.AddConsole());
var host = builder.Build();//運行給定的配置來初始化主機。只能調用一次。
await host.StartAsync();//啟動當前Silo.
return host;
}
}
}
創建客戶端
最后,我們需要配置一個客戶端與Grain進行通信,將其連接到集群(其中有一個Silo),然后調用Grain。注意,群集配置必須與我們用於Silo的配置匹配。在Orleans文檔的“ 群集和客戶端”中有關於客戶端的更多配置信息
using IGrain;
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using System;
using System.Threading.Tasks;
namespace Client
{
class Program
{
static int Main(string[] args)
{
Console.WriteLine("Hello World!");
return RunMainAsync().Result;
}
private static async Task<int> RunMainAsync()
{
try
{
using(var client = await ConnectClient())
{
await DoClientWork(client);
Console.ReadKey();
}
return 0;
}
catch(Exception ex)
{
Console.WriteLine($"\n嘗試運行客戶端時發生異常: {ex.Message}");
Console.WriteLine("請確保客戶端嘗試連接的 Silo Host 正在運行。");
Console.WriteLine("\n按任意鍵退出。");
Console.ReadKey();
return 1;
}
}
private static async Task<IClusterClient> ConnectClient()
{
IClusterClient client;
client = new ClientBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "OrleansBasics";
})
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await client.Connect();
Console.WriteLine("客戶端已成功連接到Silo Host \n");
return client;
}
private static async Task DoClientWork(IClusterClient client)
{
//從客戶端調用Grain的示例
var friend = client.GetGrain<IHello>(0);
var response = await friend.SayHello("Good morning, HelloGrain!");
Console.WriteLine("\n\n{0}\n\n", response);
}
}
}
運行應用程序
Host
Client
本文代碼范例
便捷路由
目錄 : Orleans[NET Core 3.1] 學習筆記(一).NET環境下的分布式應用程序
下一節 : Orleans[NET Core 3.1] 學習筆記(三)( 1 )本地開發配置