简介
在这一节,我们将介绍如何在Silo和Client中获取Grain及调用Grain
Grain获取方式
从Grain内部获取:
//根据特定的Key值创建或获取指定的Grain
IStudent student = GrainFactory.GetGrain(studentID);
从Client获取:
IStudent player = client.GetGrain(studentID);
应用
我们在项目中新增一个教室的概念,学生入学需要到教室先报个到才能分配到学号
1.修改 IStudent
,新增两个接口
[...]
///
/// 设置个人信息
///
/// 学号
/// 姓名
///
Task SetStudentInfo(int studentId, string studentName);
///
/// 接收消息
///
/// 消息code类型
/// 消息发送人id
/// 消息内容
///
Task ReceiveMessages(string code, object senderId, string message);
[...]
2.修改 Student
/// 学号
private int Id;
/// 姓名
private string Name;
[...]
public Task SetStudentInfo(int studentId, string studentName)
{
Id = studentId;
Name = studentName;
return Task.CompletedTask;
}
public Task ReceiveMessages(string code, object senderId, string message)
{
switch (code)
{
case "加入新同学":
{
ConsoleHelper.WriteSuccessLine($"【{Name}】:欢迎新同学");
break;
}
case "同学发言":
{
ConsoleHelper.WriteSuccessLine($"【{Name}】听到了学号为【{senderId}】的同学说的【{message}】");
break;
}
default:
{
ConsoleHelper.WriteSuccessLine($"【{Name}】:我听不懂你们在说啥");
break;
}
}
return Task.CompletedTask;
}
[...]
3.在 IGrains
中新增 IClassroom
namespace IGrains
{
///
/// 教室
///
public interface IClassroom : Orleans.IGrainWithIntegerKey
{
///
/// 报名登记并拿到学号
///
/// 姓名
///
Task Enroll(string name);
///
/// 学生入座
///
///
///
Task Seated(IStudent student);
///
/// 发言
///
/// 当前的学生
/// 发言内容
///
Task Speech(IStudent student, string message);
}
}
4.在 Grains
中新增 Classroom
using IGrains;
using Orleans;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Grains
{
///
/// 教室
///
public class Classroom : Orleans.Grain, IClassroom
{
/// 教室内的学生
private List Students = new List();
///
/// 报名登记并拿到学号
///
/// 姓名
///
public async Task Enroll(string name)
{
int studentID = Students.Count() + 1;
var aaa = this.GetPrimaryKeyLong();
IStudent student = GrainFactory.GetGrain(studentID);
await student.SetStudentInfo(studentID, name);//等待一下
Students.Add(student);
return studentID;
}
///
/// 学生入座
///
///
///
public Task Seated(IStudent student)
{
if (!Students.Contains(student))
{
return Task.FromResult(false);//没登记的学生不给坐
}
foreach (var item in Students)
{
if (item.GetPrimaryKeyLong() != student.GetPrimaryKeyLong())
{
item.ReceiveMessages("加入新同学", this.GetPrimaryKeyLong(), $"学号{student.GetPrimaryKeyLong()}的童靴加入了我们,大家欢迎");//不等待
}
}
return Task.FromResult(true);
}
///
/// 发言
///
/// 当前的学生
/// 发言内容
public Task Speech(IStudent student, string message)
{
if (!Students.Contains(student))
{
return Task.FromResult(false);//没登记的学生闭嘴
}
foreach (var item in Students)
{
if (item.GetPrimaryKeyLong() != student.GetPrimaryKeyLong())
{
item.ReceiveMessages("同学发言", (int)student.GetPrimaryKeyLong(), message);//不等待
}
}
return Task.FromResult(true);
}
}
}
5.新增新的Orleans客户端项目,创建 asp.net core mvc
项目 Client_WebMVCApp
使用NuGet引用 Microsoft.Orleans.Client(3.0.2)
新增 OrleansService
namespace Client_WebMVCApp.Services
{
public class OrleansService : IOrleansService
{
private readonly IClusterClient clusterClient;
public OrleansService()
{
clusterClient = ConnectClient().Result;
}
public T GetGrain(long integerKey) where T : IGrainWithIntegerKey
{
return clusterClient.GetGrain(integerKey);
}
///
/// 使用本地配置连接服务
///
///
private async Task ConnectClient()
{
IClusterClient client;
client = new ClientBuilder()
.UseLocalhostClustering() //配置客户端以连接到本地主机上的筒仓。
.Configure(options =>
{
options.ClusterId = "dev";
options.ServiceId = "MyHost";
})
.Build();
await client.Connect();
return client;
}
}
}
然后修改 Startup
,把Orleans配置上去
[...]
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddTransient();//注册一下Orleans
}
[...]
再修改 HomeController
,咱们来把上面注入的 OrleansService
使用起来
[...]
private readonly OrleansService _orleansService;
private readonly IClassroom _classroom;
public HomeController(ILogger logger, OrleansService orleansService)
{
_logger = logger;
_orleansService = orleansService;
_classroom = _orleansService.GetGrain(0);
}
///
/// 报名拿学号
///
/// 学生姓名
///
[HttpGet]
public async Task GetStudentId(string name)
{
var studentId = await _classroom.Enroll(name);
IStudent student = _orleansService.GetGrain(studentId);
_classroom.Seated(student);//落座,不等待它
//return Json(new { Success = true, Data = studentId, Message = "获取成功!" });
return new JsonResult(new { Success = true, Data = studentId, Message = "获取成功!" });
}
[...]
6.运行起来
我们先把 Silo_ConsoleApp
跑起来
然后把 Client_WebMVCApp
跑起来,注意,这里我的端口用的是 4003
,按照顺序请求如下接口:
http://localhost:4003/home/getstudentid?name=张三
http://localhost:4003/home/getstudentid?name=李四
http://localhost:4003/home/getstudentid?name=王二麻
我们能看到 Silo_ConsoleApp.exe
打印如下日志:
好了,大功告成。
张三、李四、王二麻三个人排着队报名入座,李四坐下的时候张三欢迎他,王二麻坐下的时候张三李四一起欢迎他,ojbk,完美
本文代码范例
GitHub仓库
便捷路由
目录 : Orleans[NET Core 3.1] 学习笔记(一).NET环境下的分布式应用程序
上一节 : Orleans[NET Core 3.1] 学习笔记(四)( 1 )创建项目
下一节 : Orleans[NET Core 3.1] 学习笔记(四)( 3 )监控Orleans Silo的方式 OrleansDashboard