欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-09-28 17:16:04
简介 在这一节,我们将介绍如何在 Silo 和 Client 中获取Grain及调用Grain Grain获取方式 从Grain内部获取: 从Client获取: 应用 我们在项目中新增一个教室的概念,学生入学需要到教室先报个到才能分配到学号 1.修改 ,新增两个接口 2.修改 3.在 中新增 4.在 ......

简介

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

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

好了,大功告成。

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

本文代码范例

github仓库

便捷路由

目录orleans[net core 3.1] 学习笔记(一).net环境下的分布式应用程序

上一节orleans[net core 3.1] 学习笔记(四)( 1 )创建项目

下一节