创建最小的 Orleans 应用程序

在本教程中,你将按照分步说明创建大多数 Orleans 应用程序通用的基础移动部件。 它设计为自包含和极简。

本教程缺乏适当的错误处理和其他对生产环境有用的基本代码。 但是,它应有助于你动手了解 Orleans 的常见应用结构,并使你能够将持续学习的重点放在与你最相关的部件上。

先决条件

项目设置

在本教程中,你将创建四个项目作为同一解决方案的一部分:

  • 包含 grain 接口的库。
  • 包含 grain 类的库。
  • 用于托管 Silo 的控制台应用。
  • 用于托管客户端的控制台应用。

在 Visual Studio 中创建结构

将默认代码替换为为每个项目提供的代码。

  1. 首先在新解决方案中创建控制台应用项目。 调用项目部件 silo 并将解决方案命名为 OrleansHelloWorld。 有关创建控制台应用的详细信息,请参阅教程:使用 Visual Studio 创建 .NET 控制台应用程序
  2. 添加另一个控制台应用项目并将其命名为 Client
  3. 添加一个类库并将其命名为 GrainInterfaces。 有关创建类库的信息,请参阅教程:使用 Visual Studio 创建 .NET 类库
  4. 添加另一个类库并将其命名为 Grains

删除默认源文件

  1. Grains 中删除 Class1.cs
  2. GrainInterfaces 中删除 Class1.cs

添加引用

  1. Grains 引用 GrainInterfaces
  2. Silo 引用 Grains
  3. 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.ServerMicrosoft.Orleans.ClientMicrosoft.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();

前面的代码:

创建客户端

最后,你需要配置一个客户端来与 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,则可以配置多个启动项目

另请参阅