T2FGame.Cluster.Orleans 1.0.9

dotnet add package T2FGame.Cluster.Orleans --version 1.0.9
                    
NuGet\Install-Package T2FGame.Cluster.Orleans -Version 1.0.9
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="T2FGame.Cluster.Orleans" Version="1.0.9" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="T2FGame.Cluster.Orleans" Version="1.0.9" />
                    
Directory.Packages.props
<PackageReference Include="T2FGame.Cluster.Orleans" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add T2FGame.Cluster.Orleans --version 1.0.9
                    
#r "nuget: T2FGame.Cluster.Orleans, 1.0.9"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package T2FGame.Cluster.Orleans@1.0.9
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=T2FGame.Cluster.Orleans&version=1.0.9
                    
Install as a Cake Addin
#tool nuget:?package=T2FGame.Cluster.Orleans&version=1.0.9
                    
Install as a Cake Tool

T2FGame.Cluster.Orleans

T2FGame 框架的分布式集群层,基于 Microsoft Orleans 实现,提供类似 ioGame 的 Broker 架构。

功能特性

  • Broker 架构:中心化消息路由,类似 ioGame BrokerServer
  • GameServer Grain:业务逻辑服务器,类似 ioGame BrokerClient
  • 负载均衡:支持轮询、随机、一致性哈希、最小负载等策略
  • 服务发现:自动注册和健康检查
  • 多数据库支持:SQL Server、PostgreSQL、MySQL、MongoDB

安装

<PackageReference Include="T2FGame.Cluster.Orleans" />

架构概述

┌─────────────────────────────────────────────────────────────┐
│                      外部网关 (Gateway)                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    BrokerGrain (消息路由)                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │ 服务器注册   │  │ 消息路由     │  │ 负载均衡    │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
└─────────────────────────────────────────────────────────────┘
          │                    │                    │
          ▼                    ▼                    ▼
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│ GameServerGrain │  │ GameServerGrain │  │ GameServerGrain │
│   (用户模块)     │  │   (战斗模块)     │  │   (房间模块)     │
│  Cmd: 1-99      │  │  Cmd: 100-199   │  │  Cmd: 200-299   │
└─────────────────┘  └─────────────────┘  └─────────────────┘

快速开始

1. 配置 Silo(服务端)

var host = Host.CreateDefaultBuilder(args)
    .UseT2FGameCluster(options =>
    {
        options.ClusterId = "T2FGameCluster";
        options.ServiceId = "T2FGame";
        options.SiloPort = 11111;
        options.GatewayPort = 30000;

        // 开发模式
        options.ClusteringProvider = ClusteringProviderType.Development;

        // 或生产模式(MongoDB)
        // options.ClusteringProvider = ClusteringProviderType.MongoDB;
        // options.PersistenceProvider = PersistenceProviderType.MongoDB;
        // options.MongoConnectionString = "mongodb://localhost:27017";
        // options.MongoDatabaseName = "T2FGame";
    })
    .ConfigureServices((context, services) =>
    {
        // 注册 Action(二选一)
        // 方式一:运行时反射扫描
        services.AddT2FGameAction(typeof(UserController).Assembly);
        // 方式二:Source Generator 生成(需要引用 T2FGame.CodeGen.Action)
        // services.AddT2FGameActionGenerated();

        // 注册 Pipeline
        services.AddActionPipeline();

        // 注册游戏服务器
        services.AddT2FGameServer(options =>
        {
            options.ServerId = "game-server-1";
            options.ServerName = "游戏服务器1";
            options.Tag = "Logic";
        });
    })
    .Build();

await host.RunAsync();

2. 配置 Client(客户端)

var host = Host.CreateDefaultBuilder(args)
    .UseT2FGameClusterClient(options =>
    {
        options.ClusterId = "T2FGameCluster";
        options.ServiceId = "T2FGame";
        options.ClusteringProvider = ClusteringProviderType.MongoDB;
        options.MongoConnectionString = "mongodb://localhost:27017";
    })
    .Build();

await host.StartAsync();

// 获取 Broker
var grainFactory = host.Services.GetRequiredService<IGrainFactory>();
var broker = grainFactory.GetGrain<IBrokerGrain>("default");

// 发送请求
var response = await broker.RouteMessageAsync(new RouteRequest
{
    CmdMerge = CmdKit.GetMergeCmd(CmdModule.User, UserCmd.Login),
    UserId = 12345,
    Data = loginRequest.ToByteArray()
});

核心组件

BrokerGrain(消息代理)

public interface IBrokerGrain : IGrainWithStringKey
{
    // 服务器管理
    Task RegisterServerAsync(GameServerInfo serverInfo);
    Task UnregisterServerAsync(string serverId);
    Task UpdateServerStatusAsync(string serverId, ServerStatus status, int load);
    Task HeartbeatAsync(string serverId);

    // 消息路由
    Task<RouteResponse> RouteMessageAsync(RouteRequest request);
    Task RouteMessageOnewayAsync(RouteRequest request);
    Task<List<RouteResponse>> BroadcastMessageAsync(RouteRequest request);
    Task<RouteResponse> RouteToTagAsync(string tag, RouteRequest request);

    // 用户绑定
    Task BindUserToServerAsync(long userId, string serverId, int? cmdMerge = null);
    Task UnbindUserAsync(long userId, int? cmdMerge = null);

    // 集群信息
    Task<ClusterInfo> GetClusterInfoAsync();
    Task<List<GameServerInfo>> GetAllServersAsync();
}

GameServerGrain(游戏服务器)

public interface IGameServerGrain : IGrainWithStringKey
{
    // 初始化
    Task InitializeAsync(GameServerInfo serverInfo);

    // 请求处理
    Task<RouteResponse> HandleRequestAsync(RouteRequest request);
    Task HandleOnewayAsync(RouteRequest request);

    // 状态管理
    Task<GameServerInfo> GetServerInfoAsync();
    Task<ServerStatus> GetStatusAsync();
    Task UpdateLoadAsync(int currentLoad);
    Task StopAsync();
}

负载均衡

支持的策略

public enum LoadBalanceStrategy
{
    RoundRobin,        // 轮询
    Random,            // 随机
    ConsistentHash,    // 一致性哈希
    LeastLoad,         // 最小负载
    WeightedRandom     // 加权随机
}

配置负载均衡

services.AddT2FGameServer(options =>
{
    options.DefaultLoadBalanceStrategy = LoadBalanceStrategy.LeastLoad;
});

用户绑定(有状态路由)

// 将用户绑定到特定服务器
await broker.BindUserToServerAsync(userId, serverId);

// 按命令绑定(如房间绑定)
await broker.BindUserToServerAsync(userId, serverId, roomCmdMerge);

// 后续该用户的请求会自动路由到绑定的服务器
var response = await broker.RouteMessageAsync(new RouteRequest
{
    UserId = userId,
    CmdMerge = roomCmdMerge,
    // ...
});

数据库配置

MongoDB(推荐)

options.ClusteringProvider = ClusteringProviderType.MongoDB;
options.PersistenceProvider = PersistenceProviderType.MongoDB;
options.MongoConnectionString = "mongodb://localhost:27017";
options.MongoDatabaseName = "T2FGame";

SQL Server

options.ClusteringProvider = ClusteringProviderType.SqlServer;
options.ConnectionString = "Server=localhost;Database=Orleans;...";

PostgreSQL

options.ClusteringProvider = ClusteringProviderType.PostgreSQL;
options.ConnectionString = "Host=localhost;Database=orleans;...";

开发模式(内存)

options.ClusteringProvider = ClusteringProviderType.Development;
options.PersistenceProvider = PersistenceProviderType.Memory;

健康检查

BrokerGrain 自动执行健康检查:

  • 每 10 秒检查一次所有服务器
  • 30 秒无心跳标记为 Unhealthy
  • 120 秒无心跳自动移除
// 自定义超时设置
services.AddT2FGameBroker(options =>
{
    options.HealthCheckIntervalSeconds = 10;
    options.ServerTimeoutSeconds = 30;
    options.AutoRemoveTimeoutSeconds = 120;
});

OrleansFlowContext

Orleans 环境下的 FlowContext 实现:

public sealed class OrleansFlowContext : FlowContext
{
    // 跨模块调用
    public async Task<RouteResponse> RouteToModuleAsync(int cmdMerge, byte[]? data = null)
    {
        var broker = GetBroker();
        return await broker.RouteMessageAsync(new RouteRequest
        {
            CmdMerge = cmdMerge,
            UserId = UserId,
            SessionId = SessionId,
            Data = data
        });
    }
}

目录结构

T2FGame.Cluster.Orleans/
├── Configuration/
│   └── ClusterConfiguration.cs      # 集群配置
├── Extensions/
│   └── ServiceCollectionExtensions.cs # 服务注册
├── Grains/
│   ├── IBrokerGrain.cs              # Broker 接口
│   ├── BrokerGrain.cs               # Broker 实现
│   ├── IGameServerGrain.cs          # GameServer 接口
│   └── GameServerGrain.cs           # GameServer 实现
├── LoadBalancing/
│   ├── LoadBalanceStrategy.cs       # 负载均衡策略枚举
│   └── ServerRegion.cs              # 服务器区域(内置负载均衡实现)
├── Models/
│   ├── RouteRequest.cs              # 路由请求
│   ├── RouteResponse.cs             # 路由响应
│   ├── GameServerInfo.cs            # 服务器信息
│   └── ClusterInfo.cs               # 集群信息
└── Services/
    └── GameServerHostedService.cs   # 托管服务

与 ioGame 对比

ioGame 概念 T2FGame 对应
BrokerServer BrokerGrain
BrokerClient GameServerGrain
BarSkeleton ActionPipeline
ExternalServer Gateway + Socket
CmdRegion ServerRegionManager
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on T2FGame.Cluster.Orleans:

Package Downloads
T2FGame

T2FGame Framework - A high-performance distributed game server framework inspired by ioGame. This meta-package includes all T2FGame components.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.9 442 12/11/2025
1.0.8 438 12/11/2025
1.0.7 442 12/11/2025
1.0.6 443 12/11/2025
1.0.5 456 12/10/2025
1.0.4 460 12/10/2025
1.0.3 456 12/9/2025
1.0.2 376 12/8/2025
1.0.1 502 12/1/2025
1.0.0 185 11/28/2025
0.0.1 373 12/8/2025