Orleans[NET Core 3.1] 学习笔记(四)( 2 )获取Grain的方式

简介

在这一节,我们将介绍如何在SiloClient中获取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 打印如下日志:

Orleans[NET Core 3.1] 学习笔记(四)( 2 )获取Grain的方式_第1张图片

好了,大功告成。

张三、李四、王二麻三个人排着队报名入座,李四坐下的时候张三欢迎他,王二麻坐下的时候张三李四一起欢迎他,ojbk,完美

本文代码范例

GitHub仓库

便捷路由

目录 : Orleans[NET Core 3.1] 学习笔记(一).NET环境下的分布式应用程序

上一节 : Orleans[NET Core 3.1] 学习笔记(四)( 1 )创建项目

下一节 : Orleans[NET Core 3.1] 学习笔记(四)( 3 )监控Orleans Silo的方式 OrleansDashboard

你可能感兴趣的:(Orleans[NET Core 3.1] 学习笔记(四)( 2 )获取Grain的方式)