zoukankan      html  css  js  c++  java
  • Orleans[NET Core 3.1] 学习笔记(四)( 2 )获取Grain的方式

    简介

    在这一节,我们将介绍如何在SiloClient中获取Grain及调用Grain

    Grain获取方式

    从Grain内部获取:

    //根据特定的Key值创建或获取指定的Grain
    IStudent student = GrainFactory.GetGrain<IStudent>(studentID);
    

    从Client获取:

    IStudent player = client.GetGrain<IStudent>(studentID);
    

    应用

    我们在项目中新增一个教室的概念,学生入学需要到教室先报个到才能分配到学号

    1.修改 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);
            [...]
    

    2.修改 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;
            }
            [...]
    

    3.在 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);
        }
    }
    

    4.在 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);
            }
        }
    }
    

    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<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配置上去

            [...]
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews(); 
                services.AddTransient<OrleansService>();//注册一下Orleans
            }
            [...]
    

    再修改 HomeController ,咱们来把上面注入的 OrleansService 使用起来

            [...]
            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 = "获取成功!" });
            }
            [...]
    

    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

  • 相关阅读:
    spring4之依赖注入的三种方式
    Hibernate之总结
    Hibernate之dynamic-update
    ThinkPhp调用webservice
    Robot Framework:Web自动化之-元素处理
    Robot Framework:Web自动化之-元素定位
    RobotFramework:python+robotframework+selenium2library测试环境部署说明文档
    Robot Framework:Httplibrary库
    URL备忘
    Windows:CMD命令备忘
  • 原文地址:https://www.cnblogs.com/amber-L/p/12193277.html
Copyright © 2011-2022 走看看