在這一節,咱們將介紹如何在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 )建立項目
下一節 :