消息订阅器:

Ray是基于Event Sourcing设计的ES/Actor框架,消息发布后需要订阅处理,订阅器主要有以下两类:

  • CoreHandler消息订阅器=RabbitSub+SubHandler
  • ToReadHandler消息订阅器=RabbitSub+SQLToReadHandler(ToReadHandler的子类)
    RabbitSub特性

RabbitSub特性是RabbitMQ消息队列订阅器。

RabbitSub特性有两个构造函数,常用的是这个:

public RabbitSubAttribute(string group, string exchange, string queue, int queueCount = 1)
  • group:通常用于分类。示例中,X-CoreHandler的group是Core,X-ToReadHandler是Read。
  • exchange:RabbitMQ中的exchange名称。
  • queue:RabbitMQ中的queue名称。
  • queueCount:消息队列数。用于消息的负载均衡。

示例:

[RabbitSub("Core", "Account", "account")]
public sealed class AccountCoreHandler : SubHandler<string, MessageInfo>
{
……
}

RabbitSub可以单独使用,用于订阅消息。


CoreHandler消息订阅器

Ray中的ESActor通过RaiseEvent方法发布事件,传递消息。Ray默认使用RabbitMQ传递消息。ESActor发起事件后,CoreHandler订阅事件,以处理事件。

实现方式是:

  • 继承SubHandler。
  • 添加RabbitSub特性。 exchange名称、queue名称与ESGrain上RabbitPub特性的标识一致。
  • 添加构造函数(必须)。
    public AccountCoreHandler(IServiceProvider svProvider) : base(svProvider)
    {
    }
  • 事件被订阅后会流转到Tell方法中,data是要处理的事件。
    public override Task Tell(byte[] bytes, IActorOwnMessage<string> data, MessageInfo msg)
    {
    switch (data)
    {
    case AmountTransferEvent value: return Task.WhenAll(task, AmountAddEventHandler(value));
    default: return task;
    }
    }
    ToReadHandler消息订阅器
  1. SQLToReadHandler

ESActor发起事件后,X-ToReadHandler订阅事件,以处理事件。X-ToReadHandler继承自X-SQLToReadHandler,X-SQLToReadHandler继承自ToReadHandler。

示例图:

X-SQLToReadHandler需要使用者继承PartSubHandler,根据使用的关系型数据库自己实现。Ray默认提供了PostgreSQL的PSQLToReadHandler。如果使用的是MySQL、SQL Server等其他关系型数据库,请自定义实现。

X-SQLToReadHandler实现细节:
修改对应关系型数据库的Integrity Constraint Violation(违反完整性约束)的异常。
可以将实例中PSQLToReadHandler当做X-ToReadHandler模板,修改if (!(t.Exception.InnerException is Npgsql.PostgresException e && e.SqlState == "23505"))即可。


说明:

当X-ToReadHandler订阅消息,消息有重放的场景,如果该消息已经得到处理,数据库中已经存在其处理后的结果,这是可能会报Integrity Constraint Violation(违反完整性约束)异常,默认不做处理,其他异常将其抛出,这是这段代码的作用。


示例模板:

public abstract class PSQLToReadHandler<K> : PartSubHandler<K, MessageInfo>
{
public PSQLToReadHandler(IServiceProvider svProvider) : base(svProvider)
{ }
public override Task Notice(byte[] data)
{
return base.Notice(data).ContinueWith(t =>
{
if (t.Exception != null)
{
//根据使用数据库,修改这个if判断
if (!(t.Exception.InnerException is Npgsql.PostgresException e && e.SqlState == "23505"))
{
throw t.Exception;
}
}
});
}
}

2. X-ToReadHandler
X-ToReadHandler订阅器主要用于订阅感兴趣的消息,将数据写入到数据库中。

实现方式是:

  • 实现SQLToReadHandler
  • ToReadHandler继承SQLToReadHandler(ToReadHandler的子类)
  • 添加RabbitSub特性。
  • 添加构造函数(必须),在构造函数中注册关注的事件。
    public AccountToReadHandler(IServiceProvider svProvider) : base(svProvider)
    {
    Register<AmountAddEvent>();
    Register<AmountTransferEvent>();
    }

    代码如下所示:

[RabbitSub("Read", "Account", "account")]
public sealed class AccountToReadHandler : PSQLToReadHandler<string>
{
public AccountToReadHandler(IServiceProvider svProvider) : base(svProvider)
{
Register<AmountAddEvent>();
Register<AmountTransferEvent>();
}
}
X-ToReadHandler消息订阅器与CoreHandler消息订阅器差异

X-ToReadHandler消息订阅器使用时,需要在构造函数中注册关心的事件,而X-CoreHandler中不需要,原因是事件在处理中需要反序列化,X-CoreHandler会对RabbitSub参数指定订阅的所有的消息反序列化,X-ToReadHandler在此基础上做了进一步的控制,在订阅的消息中只对Register的事件处理。这样做的原因:1.反序列化会消耗一定的性能,进一步控制有助于提高性能;2.Ray提供两种实现方式,为开发者扩展自定义源码提供借鉴。

总结:

  • CoreHandler消息订阅器=RabbitSub+SubHandler
  • ToReadHandler消息订阅器=RabbitSub+SQLToReadHandler(ToReadHandler的子类)
​

6.Ray-消息订阅器编写的更多相关文章

  1. SLAM+语音机器人DIY系列:(二)ROS入门——5.编写简单的消息发布器和订阅器

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  2. ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)

    一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials 创建一个发布器节点( ...

  3. 用C++编写发布器和订阅器节点

    1.转移到之前教程在catkin工作空间所创建的package路径下: $ roscd package_name/ 例子:$ roscd practice/2.在package路径下创建src目录: ...

  4. ROS 消息发布器和订阅器Publisher, Subscriber

    博客参考:https://www.2cto.com/kf/201705/639776.html 1.编写发布器节点节点(Node) 是指 ROS 网络中可执行文件.接下来,将会创建一个发布器节点(“t ...

  5. ROS:消息发布器和订阅器(c++)

    学习资料主要源自http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29 $ roscd beginner_t ...

  6. [转]RoboWare Studio的使用和发布器/订阅器的编写与测试

    原文地址:https://blog.csdn.net/han_l/article/details/77772352,转载主要方便随时查阅,如有版权要求,请及时联系. 开始ROS学习之前,先按照官网教程 ...

  7. Ros学习——Python发布器publisher和订阅器subscriber

    1.编写发布器 初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息 以每秒 10 次的频率在 chatter 上发布消息 在 ...

  8. Ros学习——C++发布器publisher和订阅器subscriber

    1.编写发布器 初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息 以每秒 10 次的频率在 chatter 上发布消息 在 ...

  9. JS-YAML -YAML 1.2 JavaScript解析器/编写器

    下载 JS-YAML -YAML 1.2 JavaScript解析器/编写器JS-YAML -YAML 1.2 JavaScript解析器/编写器 在线演示 这是YAML的实现,YAML是一种对人友好 ...

随机推荐

  1. 基于Windows下python3.4.1IDLE常用快捷键小结

    安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.ALT ...

  2. bzoj:2423: [HAOI2010]最长公共子序列

    Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0, ...

  3. 【Java学习笔记之三】java中的变量和常量

    变量和常量 在程序中存在大量的数据来代表程序的状态,其中有些数据在程序的运行过程中值会发生改变,有些数据在程序运行过程中值不能发生改变,这些数据在程序中分别被叫做变量和常量. 在实际的程序中,可以根据 ...

  4. android小说阅读源码、bilibili源码、MVP新闻源码等

    Android精选源码 一款基于 MVP+RxJava2+Retrofit2 的应用--熊猫眼 android 五子棋源码分享 android实现全国地图点击效果 android实现立体图案绘制的代码 ...

  5. spring如何控制事务

    Spring 的事务,可以说是 Spring AOP 的一种实现. AOP面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作. spring是一个容器,通过spr ...

  6. UE4 径向模糊radiu blur

    hlsl代码为: float2 ScreenMult = ; ; ] = {-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08}; float ...

  7. DEDE在图集列表中调出图集的所有图片[首页也适用]

    在include/common.func.php 中添加以下函数代码 代码如下:   // 在图集列表中调出图集的所有图片 function Getimgs($aid, $imgwith = 220, ...

  8. electron 学习笔记

    一.快速搭建一个electron 项目结构 # 克隆示例项目的仓库 $ git clone https://github.com/electron/electron-quick-start # 进入这 ...

  9. jquery 图片自动无缝滚动

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  10. NSDateFormatter相关整理

    //实例化一个NSDateFormatter对象NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; //设定时间格式,这里可 ...