Orleans 2.0 官方文档 —— 4.5 Grains - 观察者
观察者
在某些情况下,简单的消息/响应模式是不够的,客户端需要接收异步通知。例如,用户可能希望在朋友发布新的即时消息时得到通知。
客户端的观察者是一种允许异步通知客户端的机制。观察者是从IGranobserver继承的单向异步接口,它的所有方法都必须是void。grain通过像grain接口方法一样,调用它向观察者发送通知,只不过它没有返回值,因此grain不需要依赖于结果。Orleans运行时会确保单向传递通知。发布此类通知的grain,应该提供一个API来添加或删除观察者。此外,通常也很方便地暴露一个允许取消现有订阅的方法。grain开发者可以使用Orleans ObserverSubscriptionManager<T>
泛型类,来简化被观察的grain类型的开发。
要订阅通知,客户端必须首先创建一个实现观察者接口的本地C#对象。然后,它在观察器工厂上调用一个静态方法CreateObjectReference()
,将C#对象转换为一个grain引用,然后可以将该grain引用传递给通知grain上的订阅方法。
其他grain也可以使用此模型来接收异步通知。与客户端订阅不同,订阅grain只是将观察者接口实现为门面,并将引用传递给自身(例如this.AsReference<IMyGrainObserverInterface>
)。
代码示例
假设我们有一个定期向客户端发送消息的grain。为简单起见,我们示例中的消息将是一个字符串。我们首先在客户端上定义将接收消息的接口。
接口看起来像这样
public interface IChat : IGrainObserver
{void ReceiveMessage(string message);
}
唯一特别的是,接口应该继承IGrainObserver
。现在,任何想要观察这些消息的客户端,都应该实现一个类,而该类实现IChat
。
最简单的情况是这样的:
public class Chat : IChat
{public void ReceiveMessage(string message){Console.WriteLine(message);}
}
现在在服务器上,我们应该有一个grain,它将这些聊天消息发送给客户端。grain还应该有一个机制,让客户端订阅和取消订阅自己来接收通知。对于订阅,grain可以使用工具类ObserverSubscriptionManager
。如果您试图订阅已订阅的观察者(或取消订阅一个未订阅的观察者),则此类会抛出一个OrleansException
,因此,对此次情况,使用IsSubscribed()
方法,或处理OrleansException
,就很重要:
class HelloGrain : Grain, IHello
{private ObserverSubscriptionManager<IChat> _subsManager;public override async Task OnActivateAsync(){// We created the utility at activation time._subsManager = new ObserverSubscriptionManager<IChat>();await base.OnActivateAsync();}// Clients call this to subscribe.public Task Subscribe(IChat observer){if (!_subsManager.IsSubscribed(observer)){_subsManager.Subscribe(observer);}return Task.CompletedTask;}//Also clients use this to unsubscribe themselves to no longer receive the messages.public Task UnSubscribe(IChat observer){if (_subsManager.IsSubscribed(observer)){_subsManager.Unsubscribe(observer);}return Task.CompletedTask;}
}
要将消息发送到客户端,可以使用ObserverSubscriptionManager<IChat>
实例的Notify
方法。该方法接收一个Action<T>
方法或lambda表达式(此处T
为IChat
类型)。您可以调用接口上的任何方法将其发送给客户端。在我们的例子中,我们只有一个方法ReceiveMessage
,我们在服务器上的发送代码如下所示:
public Task SendUpdateMessage(string message)
{_subsManager.Notify(s => s.ReceiveMessage(message));return Task.CompletedTask;
}
现在,我们的服务器有一个向观察者客户端发送消息的方法,两种方法用于订阅/取消订阅,客户端实现了一个类,以便能够观察grain消息。最后一步是使用我们之前实现的Chat
类,在客户端上创建一个观察者引用,并让它在订阅之后接收消息。
代码如下所示:
//First create the grain reference
var friend = GrainClient.GrainFactory.GetGrain<IHello>(0);
Chat c = new Chat();//Create a reference for chat usable for subscribing to the observable grain.
var obj = await GrainClient.GrainFactory.CreateObjectReference<IChat>(c);
//Subscribe the instance to receive messages.
await friend.Subscribe(obj);
现在,只要服务器上的grain调用该SendUpdateMessage
方法,所有订阅的客户端都将收到该消息。在我们的客户端代码中,变量c
中的Chat
实例,将接收消息并将其输出到控制台。
注意:传递给CreateObjectReference
的对象是通过一个WeakReference<T>
来保存的,因此,如果不存在其他引用,则将被垃圾收集。用户应该为每个不希望被垃圾收集的观察者,保留一个引用。
注意:观察者本质上是不可靠的,因为您不会得到任何响应,来知道消息是被接收和处理,或者由于分布式系统中可能出现的任何情况而导致消息失败。因此,您的观察者应该定期对grain进行轮询,或使用任何其他机制,来确保他们收到了他们应该收到的所有消息。在某些情况下,您可以承受丢失某些消息的代价,并且不需要任何额外的机制,但如果您需要确保所有观察者始终接收消息,并且正在接收所有消息,则定期重新订阅并轮询观察者grain,都有助于确保最终处理所有消息。
Orleans 2.0 官方文档 —— 4.5 Grains - 观察者相关推荐
- Orleans 2.0 官方文档 —— 4.1 Grains - 开发一个Grain
设置 在编写实现grain类的代码之前,请新建一个面向.NET Standard(首选).或.NET Framework 4.6.1或更高版本的类库项目(如果由于依赖性而无法使用.NET Standa ...
- Orleans 2.0 官方文档 —— 4.4 Grains - 定时器和提醒器(Reminder)
定时器和提醒器(Reminder) Orleans运行时提供了两种机制,称为定时器和提醒器,使开发人员能够指定grain的周期性行为. 计时器 定时器说明 定时器用于创建不需要跨越多个激活(grain ...
- Orleans 2.0 官方文档中文版 (闫辉)
目录 第一章 概览 1.1 概览 -> 介绍 1.2 概览 -> 优点 1.3 概览 -> 常见问题 1.4 概览 -> Orleans 2.0 1.5 概览 -> Or ...
- Orleans 2.0 官方文档 —— 6.8.4 部署 - 多集群支持 - silo的配置
Orleans silo的配置 为了快速了解到概貌,我们将在下面的XML语法中,显示所有相关配置参数(包括可选配置参数): <?xml version="1.0" encod ...
- Orleans 2.0 官方文档 —— 开发一个Grain
设置 在编写实现grain类的代码之前,请新建一个面向.NET Standard(首选).或.NET Framework 4.6.1或更高版本的类库项目(如果由于依赖性而无法使用.NET Standa ...
- Orleans 2.0 官方文档 —— 3.1 核心概念 - 什么是grain
什么是grain? grain是Orleans编程模型的关键原语.grain是Orleans应用程序的构建块,它们是隔离的.分布式的.持久性的原子单元.grain是表示应用程序实体的对象.就像在经典的 ...
- Orleans 2.0 官方文档 —— 4.8.1 Grains - Grain持久化 - grain持久化的目标
grain持久化的目标 允许不同的grain类型,使用不同类型的存储提供程序(例如,一个使用Azure表,一个使用ADO.NET),或相同类型的存储提供程序但具有不同的配置(例如,两者都使用Azure ...
- Orleans 2.0 官方文档 —— 5.2 集群和客户端 - silo的生命周期
silo的生命周期 概述 Orleans silo使用可观察的生命周期(参见Orleans Lifecycle),来有序地启动和关闭Orleans系统以及应用程序层组件. 阶段 Orleans Sil ...
- Orleans 2.0 官方文档 —— 1.1 概览 - 介绍
介绍 Orleans是一个框架,它提供了一种简单的方法来构建分布式大规模计算应用程序,而无需学习和应用复杂的并发或其他扩展模式. 背景 云应用程序和服务本质上是并行和分布式的.它们也具有交互性和动态性 ...
最新文章
- linux救援模式无法识别分区,Linux操作系统出现严重故障后的救援模式
- javaScript的调试(二)
- PPF(Point Pair Features)原理及实战技巧
- 2021年全球十大工程成就,中国有几个? | 科技袁人
- java fft 频谱算法_快速傅里叶变换(FFT)算法原理及代码解析
- 几个改变世界的java工具
- java 等分切割图片_java 将list按指定大小等分,最后多余的单独一份
- transferwise怎么提现_收款工具transfer wise介绍(多币种、可收CJ联盟)
- 栈和队列的Java实现
- c语言playsound参数,通达信playsound函数
- 计算机毕业设计情况进展记录表,南京理工大学泰州科技学院毕业设计(论文)进展情况记录表.doc...
- 关于pc端微信登录前后端分离的java后台开发
- winEdt下编辑报错:Something‘s wrong--perhaps a missing \item. \end{thebibliography}
- 04.ElasticSearch之IK分词器的安装与使用
- 计算机无法ping打印机,打印机故障:测试页打印失败是否参阅打印疑难解答已或得帮助...
- java:AXIS调用webService接口,返回String类型xml,并用dom4j简单解析xml
- 快速通过论文相似度检测
- 联想台式机计算机接口,接口篇:四款产品接口配置横向对比_联想ThinkCentre台式电脑_台式电脑评测-中关村在线...
- Firebase使用总结(早期)
- mysql计算折纸_折纸飞机实验报告.doc
热门文章
- 【Vue】9 - 组件(全局、局部)、通信(props、$meit、$refs)、插槽slot、component、$nextTick等
- MySQL(InnoDB剖析):24---B+树索引(聚集索引与非聚集索引(辅助索引))、B+树索引的分裂
- 多线程【全面学习 图文精讲】
- java 替换全角为半角 半角转全角
- Flutter 之简洁实用的图片编辑器
- GIT的使用总结/GIT如和获取历史版本项目
- opencv 内存数据转matlab,OpenCV:IplImage, CvMat, Mat 相互转换
- VQA系列论文(五)
- ymb是什么缩写_【快看】skr、xswl、zqsg……00后的这些暗语到底是什么意思?
- Matlab之Simulink子系统及模块封装