Orleans 2.0官方文件(閆輝的個人翻譯)——2.1 入門教程1:Orleans基礎
教程1—— 建立一個極小的Orleans應用程式
本教程提供了有關建立基本功能的Orleans應用程式的分步說明。它被設計為自包含且極盡簡約,具有以下特徵:
- 它僅依賴於NuGet包
- 它已在使用Orleans 2.2.0的Visual Studio 2017中進行了測試
- 它不依賴於外部儲存
請記住,這只是一個教程,缺少適當的錯誤處理和其他對生產環境有用的好東西。但是,它應該有助於讀者真實地瞭解Orleans的結構,並將重點放在與他們最相關的部分上。
專案設定
在本教程中,我們將建立4個專案:
- 包含grain介面的庫
- 包含grain類的庫
- 一個控制檯應用程式,作為Silo的宿主
- 一個控制檯應用程式,作為Client的宿主
完成本教程後,完整的解決方案應如下所示:
在Visual Studio中建立結構
注意:您可以在c#中使用每個專案的預設專案型別。您將使用下面為每個專案指定的程式碼替換預設程式碼。您可能還需要新增using
語句。
- 首先在新解決方案中建立一個控制檯應用程式(.NET Core)專案。將此專案命名為
Silo
,並將解決方案命名為OrleansHelloWorld
。 - 新增另一個控制檯應用程式(.NET Core)專案並命名為
Client
。 - 新增類庫(.NET Standard)並命名為
GrainInterfaces
- 新增另一個類庫(.NET Standard)並命名為
Grains
。
刪除預設原始檔
- 從Grains中刪除Class1.cs
- 從GrainInterfaces中刪除Class1.cs
新增引用
Grains
參考GrainInterfaces
。Silo
參考GrainInterfaces
和Grains
。Client
參考GrainInterfaces
。
新增Orleans NuGet包
- 對於Silo專案,新增
Microsoft.Orleans.Server
NuGet包。 - 在Client專案中,新增
Microsoft.Orleans.Client
- 對GrainInterfaces和Grains專案,新增
Microsoft.Orleans.Core.Abstractions
包和Microsoft.Orleans.CodeGenerator.MSBuild
包。 - 在Grains專案中,新增
Microsoft.Extensions.Logging.Abstractions
用於記錄的包。 - 對於Client和Silo專案,新增
Microsoft.Extensions.Logging.Console
,以便他們可以在其控制檯視窗中列印日誌。
Microsoft.Orleans.Server和
Microsoft.Orleans.Client
是元資料包,它們會在Silo和Client端,帶來您最有可能需要的依賴。
Microsoft.Orleans.Core.Abstractions
到處都需要。它包括在Microsoft.Orleans.Server
和Microsoft.Orleans.Client
。
Microsoft.Orleans.CodeGenerator.MSBuild
自動生成呼叫grain越過機器邊界所需的程式碼。所以在GrainInterfaces
和Grains
專案中需要它它。
定義grain interface
在GrainInterfaces專案中,新增一個IHello.cs
程式碼檔案並在其中定義以下IHello介面:
using System.Threading.Tasks;
namespace OrleansBasics
{
public interface IHello : Orleans.IGrainWithIntegerKey
{
Task<string> SayHello(string greeting);
}
}
定義grain類
在Grains專案中,新增一個HelloGrain.cs
程式碼檔案,並在其中定義以下類:
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace OrleansBasics
{
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 message received: greeting = '{greeting}'");
return Task.FromResult($"\n Client said: '{greeting}', so HelloGrain says: Hello!");
}
}
}
建立Silo - Program.cs
在這一步中,我們新增程式碼來初始化將承載和執行我們的grain的伺服器 —— 一個silo。我們將在這裡使用開發叢集提供程式,以便我們可以在本地執行所有內容,而不依賴於外部儲存系統。您可以在Orleans文件的“ 本地開發配置”頁面中找到更多關於這一點的資訊。我們將執行一個包含單個silo的叢集。
將以下程式碼新增到Silo專案的Program.cs中:
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
namespace OrleansBasics
{
public class Program
{
public static int Main(string[] args)
{
return RunMainAsync().Result;
}
private static async Task<int> RunMainAsync()
{
try
{
var host = await StartSilo();
Console.WriteLine("\n\n Press Enter to terminate...\n\n");
Console.ReadLine();
await host.StopAsync();
return 0;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return 1;
}
}
private static async Task<ISiloHost> StartSilo()
{
// define the cluster configuration
var builder = new SiloHostBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "OrleansBasics";
})
.ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(HelloGrain).Assembly).WithReferences())
.ConfigureLogging(logging => logging.AddConsole());
var host = builder.Build();
await host.StartAsync();
return host;
}
}
}
建立Client - Program.cs
最後,我們需要配置一個Client來與我們的grain進行通訊,將它連線到叢集(其中有一個silo),然後呼叫grain。請注意,叢集配置必須與我們用於silo的配置相匹配。在Orleans文件的Clusters and Clients部分中有關於客戶端的更多資訊。
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using System;
using System.Threading.Tasks;
namespace OrleansBasics
{
public class Program
{
static int Main(string[] args)
{
return RunMainAsync().Result;
}
private static async Task<int> RunMainAsync()
{
try
{
using (var client = await ConnectClient())
{
await DoClientWork(client);
Console.ReadKey();
}
return 0;
}
catch (Exception e)
{
Console.WriteLine($"\nException while trying to run client: {e.Message}");
Console.WriteLine("Make sure the silo the client is trying to connect to is running.");
Console.WriteLine("\nPress any key to exit.");
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("Client successfully connected to silo host \n");
return client;
}
private static async Task DoClientWork(IClusterClient client)
{
// example of calling grains from the initialized client
var friend = client.GetGrain<IHello>(0);
var response = await friend.SayHello("Good morning, HelloGrain!");
Console.WriteLine("\n\n{0}\n\n", response);
}
}
}
執行該應用程式
構建解決方案並執行Silo。在收到Silo正在執行的確認訊息後(“按Enter鍵終止...”),執行客戶端。成功看起來像這樣: