创建最小的 Orleans 应用程序
在本教程中,你将按照分步说明创建大多数 Orleans 应用程序通用的基础移动部件。 它设计为自包含和极简。
本教程缺乏适当的错误处理和其他对生产环境有用的基本代码。 但是,它应有助于你动手了解 Orleans 的常见应用结构,并使你能够将持续学习的重点放在与你最相关的部件上。
先决条件
项目设置
在本教程中,你将创建四个项目作为同一解决方案的一部分:
- 包含 grain 接口的库。
- 包含 grain 类的库。
- 用于托管 Silo 的控制台应用。
- 用于托管客户端的控制台应用。
在 Visual Studio 中创建结构
将默认代码替换为为每个项目提供的代码。
- 首先在新解决方案中创建控制台应用项目。 调用项目部件 silo 并将解决方案命名为
OrleansHelloWorld
。 有关创建控制台应用的详细信息,请参阅教程:使用 Visual Studio 创建 .NET 控制台应用程序。 - 添加另一个控制台应用项目并将其命名为
Client
。 - 添加一个类库并将其命名为
GrainInterfaces
。 有关创建类库的信息,请参阅教程:使用 Visual Studio 创建 .NET 类库。 - 添加另一个类库并将其命名为
Grains
。
删除默认源文件
- 从 Grains 中删除 Class1.cs。
- 从 GrainInterfaces 中删除 Class1.cs。
添加引用
- Grains 引用 GrainInterfaces。
- Silo 引用 Grains。
- Client 引用 GrainInterfaces。
添加 Orleans NuGet 包
Project | NuGet 包 |
---|---|
Silo | Microsoft.Orleans.Server Microsoft.Extensions.Logging.Console Microsoft.Extensions.Hosting |
客户端 | Microsoft.Orleans.Client Microsoft.Extensions.Logging.Console Microsoft.Extensions.Hosting |
GrainInterfaces | Microsoft.Orleans.Sdk |
Grains | Microsoft.Orleans.Sdk Microsoft.Extensions.Logging.Abstractions |
Microsoft.Orleans.Server
、Microsoft.Orleans.Client
和 Microsoft.Orleans.Sdk
是元包,引入了你很可能需要在 silo 和客户端上使用的依赖项。 有关添加包引用的详细信息,请参阅 dotnet 添加包或使用 NuGet 包管理器在 Visual Studio 中安装和管理包。
定义 grain 接口
在 GrainInterfaces 项目中,添加 IHello.cs 代码文件并在其中定义以下 IHello
接口:
namespace GrainInterfaces;
public interface IHello : IGrainWithIntegerKey
{
ValueTask<string> SayHello(string greeting);
}
定义 grain 类
在 Grains 项目中,添加 HelloGrain.cs 代码文件并在其中定义以下类:
using GrainInterfaces;
using Microsoft.Extensions.Logging;
namespace Grains;
public class HelloGrain : Grain, IHello
{
private readonly ILogger _logger;
public HelloGrain(ILogger<HelloGrain> logger) => _logger = logger;
ValueTask<string> IHello.SayHello(string greeting)
{
_logger.LogInformation("""
SayHello message received: greeting = "{Greeting}"
""",
greeting);
return ValueTask.FromResult($"""
Client said: "{greeting}", so HelloGrain says: Hello!
""");
}
}
创建 Silo
若要创建 Silo 项目,请添加代码以初始化承载和运行 grain 的服务器 - silo。 使用 localhost 群集提供程序,该提供程序允许在本地运行所有内容,而无需依赖外部存储系统。 有关详细信息,请参阅本地开发配置。 在此示例中,运行包含单个 silo 的群集。
将以下代码添加到 Silo 项目的 Program.cs 中:
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
IHostBuilder builder = Host.CreateDefaultBuilder(args)
.UseOrleans(silo =>
{
silo.UseLocalhostClustering()
.ConfigureLogging(logging => logging.AddConsole());
})
.UseConsoleLifetime();
using IHost host = builder.Build();
await host.RunAsync();
前面的代码:
- 将 IHost 配置为将 Orleans 与 UseOrleans 方法一起使用。
- 指定 localhost 群集提供程序应与 UseLocalhostClustering(ISiloBuilder, Int32, Int32, IPEndPoint, String, String) 方法一起使用。
- 运行
host
并等待进程终止,方法是侦听 Ctrl+C 或SIGTERM
。
创建客户端
最后,你需要配置一个客户端来与 grain 通信,将该客户端连接到群集(其中包含单个 silo),然后调用 grain。 群集配置必须与用于 silo 的配置相匹配。 有关详细信息,请参阅群集和客户端
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using GrainInterfaces;
IHostBuilder builder = Host.CreateDefaultBuilder(args)
.UseOrleansClient(client =>
{
client.UseLocalhostClustering();
})
.ConfigureLogging(logging => logging.AddConsole())
.UseConsoleLifetime();
using IHost host = builder.Build();
await host.StartAsync();
IClusterClient client = host.Services.GetRequiredService<IClusterClient>();
IHello friend = client.GetGrain<IHello>(0);
string response = await friend.SayHello("Hi friend!");
Console.WriteLine($"""
{response}
Press any key to exit...
""");
Console.ReadKey();
await host.StopAsync();
运行应用程序
生成解决方案并运行 Silo。 在收到指出 Silo正在运行的确认消息后,运行客户端。
若要从命令行启动 Silo,请在包含 Silo 项目文件的目录中运行以下命令:
dotnet run
在 Silo 启动过程中,你将看到大量输出。 看到以下消息后,即可运行客户端:
Application started. Press Ctrl+C to shut down.
在客户端项目目录中,在单独的终端窗口中运行相同的 .NET CLI 命令以启动客户端:
dotnet run
有关运行 .NET 应用的详细信息,请参阅 dotnet run。 如果使用的是 Visual Studio,则可以配置多个启动项目。