Orleans的入门教程
官方Hello World 地址
https://github.com/dotnet/orleans/tree/master/Samples/2.0/HelloWorld
Doc地址
http://dotnet.github.io/orleans/Documentation/tutorials_and_samples/Hello-World.html
手绘流程图

三个项目
主简仓 网关配置

使用的Nuget:
Microsoft.Extensions.Logging.Console V2.1.1
Microsoft.Orleans.Server V2.1.2
using Microsoft.Extensions.Logging;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Net;
using System.Threading.Tasks;
namespace OrleansGateway
{
class Program
{
static void Main(string[] args)
{
var Host = StartHost();
bool IsExit = true;
while (IsExit)
{
string read = Console.ReadLine();
if (read == "Exit")
{
IsExit = false;
Host.Result.StopAsync();
}
}
}
/// <summary>
/// 在本地启动一个Host
/// </summary>
/// <returns></returns>
static async Task<ISiloHost> StartHost() {
var builder = new SiloHostBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
//ClusterId为集群名称 相同的名称才能被分配到一个集群中
options.ClusterId = "dev";
//当前服务的名称
options.ServiceId = "Gateway";
})
.ConfigureLogging(logging => logging.AddConsole());
var host = builder.Build();
await host.StartAsync();
Console.WriteLine("启动成功");
return host;
}
}
}
UseLocalhostClustering()启动的地址是127.0.0.1 是不支持局域网连接的,如果需要配置外网支持 则嵌入已下代码
static class Exstatic {
public static ISiloHostBuilder UseLocalNetworkhostClustering(
this ISiloHostBuilder builder,
int siloPort = EndpointOptions.DEFAULT_SILO_PORT,
int gatewayPort = EndpointOptions.DEFAULT_GATEWAY_PORT,
IPEndPoint primarySiloEndpoint = null)
{
builder.Configure<EndpointOptions>(options =>
{
options.AdvertisedIPAddress = GetInternalIp();
options.SiloPort = siloPort;
options.GatewayPort = gatewayPort;
});
builder.UseDevelopmentClustering(primarySiloEndpoint ?? new IPEndPoint(GetInternalIp(), siloPort));
builder.Configure<ClusterMembershipOptions>(options => options.ExpectedClusterSize = 1);
return builder;
}
public static IPAddress GetInternalIp()
{
IPHostEntry myEntry = Dns.GetHostEntry(Dns.GetHostName());
return myEntry.AddressList.FirstOrDefault(e => e.AddressFamily.ToString().Equals("InterNetwork"));
}
结果:

支持类:
OrleansSupport
使用的Nuget:
Microsoft.Orleans.Core V2.1.2
Microsoft.Orleans.OrleansCodeGenerator.Build V2.1.2

using Orleans;
using System;
using System.Threading.Tasks;
namespace IGoods
{
public interface IGoods: IGrainWithIntegerKey
{
/// <summary>
/// 商品服务测试接口
/// </summary>
/// <returns></returns>
Task<string> GetGoodsDescribe();
}
}
using Orleans;
using System;
using System.Threading.Tasks;
namespace IShoppingRecord
{
public interface IShoppingRecord: IGrainWithIntegerKey
{
/// <summary>
/// 购物记录服务测试接口
/// </summary>
/// <returns></returns>
Task<string> GetShoppingRecordDescribe();
}
}
Goods项目
引入项目IGoods IShoppingRecord
新建类库GoodsServer 引用 IGoods
使用的Nuget包
Microsoft.Orleans.Core V2.12
Microsoft.Orleans.OrleansCodeGenerator.Build V2.12
using Orleans;
using System;
using System.Threading.Tasks;
namespace GoodsServer
{
public class GoodsServer : Grain, IGoods.IGoods
{
public Task<string> GetGoodsDescribe()
{
return Task.FromResult("商品服务调用成功");
}
}
}
新建Goods项目
新建GoodsServer类库 添加项目IGoods,IShoppingRecord

使用的Nuget包:
Microsoft.Orleans.Client V2.1.2
Microsoft.Orleans.Server V2.1.2
Microsoft.Extensions.Logging.Console V2.1.1
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace Goods
{
class Program
{
static void Main(string[] args)
{
//本服务开放端口
int silePort = 11113;
//主简仓网关端口
int gatewayPort = 30000;
//主简仓开放端口
int mainSiloPort = 11111;
//由于向网关添加一个服务处理需要多一些时间
//所以在程序运行后马上获取服务可能会抛出获取不到的异常
//详情请看5、常见问题
var host = StartHost(silePort, gatewayPort, mainSiloPort);
var client = StartClient(gatewayPort);
while (true)
{
string ReadLine = Console.ReadLine();
if (ReadLine=="Exit")
{
host.Result.StopAsync().Wait();
client.Result.Close();
break;
}
else if (ReadLine=="Goods")
{
try
{
IGoods.IGoods goods = client.Result.GetGrain<IGoods.IGoods>(0);
Console.WriteLine(goods.GetGoodsDescribe().Result);
}
catch (Exception e)
{
Console.WriteLine("服务暂时还没有启动完成 请稍后再试"+e.Message);
}
}
else if (ReadLine == "ShoppingRecord")
{
try
{
IShoppingRecord.IShoppingRecord shoppingRecord = client.Result.GetGrain<IShoppingRecord.IShoppingRecord>(0);
Console.WriteLine(shoppingRecord.GetShoppingRecordDescribe().Result);
}
catch (Exception e)
{
Console.WriteLine("服务暂时还没有启动完成 请稍后再试" + e.Message);
}
}
}
}
/// <summary>
/// 在本地启动一个Host
/// </summary>
/// <returns></returns>
static async Task<ISiloHost> StartHost(int silePort,int gatewayPort,int mainSiloPort)
{
var builder = new SiloHostBuilder()//IPAddress.Loopback为127.0.0.1
//.UseLocalhostClustering()
.UseDevelopmentClustering(new IPEndPoint(IPAddress.Loopback, mainSiloPort))
.ConfigureEndpoints(siloPort: silePort, gatewayPort: gatewayPort)
.Configure<ClusterOptions>(options =>
{
//ClusterId为集群名称 相同的名称才能被分配到一个集群中
options.ClusterId = "dev";
//当前服务的名称
options.ServiceId = "GoodsServer";
})
//注入打印消息的入口
.ConfigureLogging(logging => logging.AddConsole());
//进行构建
var host = builder.Build();
//启动服务
await host.StartAsync();
Console.WriteLine("服务启动成功");
return host;
}
/// <summary>
/// 连接Orleans仓库
/// </summary>
/// <param name="GatewayPort"></param>
/// <returns></returns>
static async Task<IClusterClient> StartClient(int gatewayPort) {
IClusterClient client = new ClientBuilder()
//与主简仓进行连接
.UseStaticClustering(new IPEndPoint[] { new IPEndPoint(IPAddress.Loopback, gatewayPort) })
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "GoodsClient";
})
//配置刷新简仓的时间 一般来说不会这么短
.Configure<GatewayOptions>(d => d.GatewayListRefreshPeriod = TimeSpan.FromSeconds(5))
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await client.Connect();
Console.WriteLine("已经成功连上网关");
return client;
}
}
}
新建ShoppingRecord项目
新建ShoppingRecordServer类库添加项目IGoods,IShoppingRecord

使用的Nuget包:
Microsoft.Orleans.Client V2.1.2
Microsoft.Orleans.Server V2.1.2
Microsoft.Extensions.Logging.Console V2.1.1
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace ShoppingRecord
{
class Program
{
static void Main(string[] args)
{
//本服务开放端口
int silePort = 11112;
//主简仓网关端口
int gatewayPort = 30000;
//主简仓开放端口
int mainSiloPort = 11111;
var host = StartHost(silePort, gatewayPort, mainSiloPort);
var client = StartClient(gatewayPort);
//由于向网关添加一个服务处理需要多一些时间
//所以可能会抛出获取不到的异常
//详情请看5、常见问题
while (true)
{
string ReadLine = Console.ReadLine();
if (ReadLine == "Exit")
{
host.Result.StopAsync().Wait();
client.Result.Close();
break;
}
else if (ReadLine == "Goods")
{
try
{
IGoods.IGoods goods = client.Result.GetGrain<IGoods.IGoods>(0);
Console.WriteLine(goods.GetGoodsDescribe().Result);
}
catch (Exception e)
{
Console.WriteLine("服务暂时还没有启动完成 请稍后再试" + e.Message);
}
}
else if (ReadLine == "ShoppingRecord")
{
try
{
IShoppingRecord.IShoppingRecord shoppingRecord = client.Result.GetGrain<IShoppingRecord.IShoppingRecord>(0);
Console.WriteLine(shoppingRecord.GetShoppingRecordDescribe().Result);
}
catch (Exception e)
{
Console.WriteLine("服务暂时还没有启动完成 请稍后再试" + e.Message);
}
}
}
}
/// <summary>
/// 在本地启动一个Host
/// </summary>
/// <returns></returns>
static async Task<ISiloHost> StartHost(int silePort, int gatewayPort, int mainSiloPort)
{
var builder = new SiloHostBuilder()//IPAddress.Loopback为127.0.0.1
.UseDevelopmentClustering(new IPEndPoint(IPAddress.Loopback, mainSiloPort))
.ConfigureEndpoints(siloPort: silePort, gatewayPort: gatewayPort)
.Configure<ClusterOptions>(options =>
{
//ClusterId为集群名称 相同的名称才能被分配到一个集群中
options.ClusterId = "dev";
//当前服务的名称
options.ServiceId = "ShoppingRecordServer";
})
//注入打印消息的入口
.ConfigureLogging(logging => logging.AddConsole());
//进行构建
var host = builder.Build();
//启动服务
await host.StartAsync();
Console.WriteLine("服务启动成功");
return host;
}
/// <summary>
/// 连接Orleans仓库
/// </summary>
/// <param name="gatewayPort"></param>
/// <returns></returns>
static async Task<IClusterClient> StartClient(int gatewayPort)
{
IClusterClient client = new ClientBuilder()
.UseStaticClustering(new IPEndPoint[] { new IPEndPoint(IPAddress.Loopback, gatewayPort) })
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "ShoppingRecordClient";
})
//配置刷新简仓的时间 一般来说不会这么短
.Configure<GatewayOptions>(d => d.GatewayListRefreshPeriod = TimeSpan.FromSeconds(5))
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await client.Connect();
Console.WriteLine("已经成功连上网关");
return client;
}
}
}
结果
先跑主简仓
然后是Goods、 ShoppingRecord

注:这次配置的教程是非可靠部署的配置,也就是不需要三方存储信息 如(Sql、Azuer) 只需要知道网关端口就可以进行连接。官方Demo是本地开发配置,应该是不能有多个服务相互调用的
在连接网关成功后获取服务可能会抛出获取不到的错误 稍后试试就行了 在部分异常会有说明
文档地址:
Demo下载地址
https://github.com/2821840032/MyOrleansDemo
来源:https://www.cnblogs.com/AnAng/p/9892866.html