在这一节,咱们将介绍如何在Silo和Client中获取Grain及调用Grainhtml
从Grain内部获取:git
//根据特定的Key值建立或获取指定的Grain IStudent student = GrainFactory.GetGrain<IStudent>(studentID);
从Client获取:github
IStudent player = client.GetGrain<IStudent>(studentID);
咱们在项目中新增一个教室的概念,学生入学须要到教室先报个到才能分配到学号web
IStudent
,新增两个接口[...] /// <summary> /// 设置我的信息 /// </summary> /// <param name="studentId">学号</param> /// <param name="studentName">姓名</param> /// <returns></returns> Task SetStudentInfo(int studentId, string studentName); /// <summary> /// 接收消息 /// </summary> /// <param name="code">消息code类型</param> /// <param name="senderId">消息发送人id</param> /// <param name="message">消息内容</param> /// <returns></returns> Task ReceiveMessages(string code, object senderId, string message); [...]
Student
/// <summary> 学号 </summary> private int Id; /// <summary> 姓名 </summary> 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; } [...]
IGrains
中新增 IClassroom
namespace IGrains { /// <summary> /// 教室 /// </summary> public interface IClassroom : Orleans.IGrainWithIntegerKey { /// <summary> /// 报名登记并拿到学号 /// </summary> /// <param name="name">姓名</param> /// <returns></returns> Task<int> Enroll(string name); /// <summary> /// 学生入座 /// </summary> /// <param name="student"></param> /// <returns></returns> Task<bool> Seated(IStudent student); /// <summary> /// 发言 /// </summary> /// <param name="student">当前的学生</param> /// <param name="message">发言内容</param> /// <returns></returns> Task<bool> Speech(IStudent student, string message); } }
Grains
中新增 Classroom
using IGrains; using Orleans; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Grains { /// <summary> /// 教室 /// </summary> public class Classroom : Orleans.Grain, IClassroom { /// <summary> 教室内的学生 </summary> private List<IStudent> Students = new List<IStudent>(); /// <summary> /// 报名登记并拿到学号 /// </summary> /// <param name="name">姓名</param> /// <returns></returns> public async Task<int> Enroll(string name) { int studentID = Students.Count() + 1; var aaa = this.GetPrimaryKeyLong(); IStudent student = GrainFactory.GetGrain<IStudent>(studentID); await student.SetStudentInfo(studentID, name);//等待一下 Students.Add(student); return studentID; } /// <summary> /// 学生入座 /// </summary> /// <param name="student"></param> /// <returns></returns> public Task<bool> 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); } /// <summary> /// 发言 /// </summary> /// <param name="student">当前的学生</param> /// <param name="message">发言内容</param> public Task<bool> 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); } } }
asp.net core mvc
项目 Client_WebMVCApp
使用NuGet引用 Microsoft.Orleans.Client(3.0.2)
mvc
新增 OrleansService
app
namespace Client_WebMVCApp.Services { public class OrleansService : IOrleansService { private readonly IClusterClient clusterClient; public OrleansService() { clusterClient = ConnectClient().Result; } public T GetGrain<T>(long integerKey) where T : IGrainWithIntegerKey { return clusterClient.GetGrain<T>(integerKey); } /// <summary> /// 使用本地配置链接服务 /// </summary> /// <returns></returns> private async Task<IClusterClient> ConnectClient() { IClusterClient client; client = new ClientBuilder() .UseLocalhostClustering() //配置客户端以链接到本地主机上的筒仓。 .Configure<ClusterOptions>(options => { options.ClusterId = "dev"; options.ServiceId = "MyHost"; }) .Build(); await client.Connect(); return client; } } }
而后修改 Startup
,把Orleans配置上去asp.net
[...] public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddTransient<OrleansService>();//注册一下Orleans } [...]
再修改 HomeController
,我们来把上面注入的 OrleansService
使用起来async
[...] private readonly OrleansService _orleansService; private readonly IClassroom _classroom; public HomeController(ILogger<HomeController> logger, OrleansService orleansService) { _logger = logger; _orleansService = orleansService; _classroom = _orleansService.GetGrain<IClassroom>(0); } /// <summary> /// 报名拿学号 /// </summary> /// <param name="name">学生姓名</param> /// <returns></returns> [HttpGet] public async Task<IActionResult> GetStudentId(string name) { var studentId = await _classroom.Enroll(name); IStudent student = _orleansService.GetGrain<IStudent>(studentId); _classroom.Seated(student);//落座,不等待它 //return Json(new { Success = true, Data = studentId, Message = "获取成功!" }); return new JsonResult(new { Success = true, Data = studentId, Message = "获取成功!" }); } [...]
咱们先把 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
打印以下日志:
好了,大功告成。
张3、李4、王二麻三我的排着队报名入座,李四坐下的时候张三欢迎他,王二麻坐下的时候张三李四一块儿欢迎他,ojbk,完美
目录 : Orleans[NET Core 3.1] 学习笔记(一).NET环境下的分布式应用程序
上一节 :Orleans[NET Core 3.1] 学习笔记(四)( 1 )建立项目
下一节 :