你能够订阅一个接口,然后发布基于这个接口的实现。

让我们看下一个示例。我有一个接口IAnimal和两个实现CatDog

public interface IAnimal
{
string Name { get; set; }
} public class Cat : IAnimal
{
public string Name { get; set; }
public string Meow { get; set; }
} public class Dog : IAnimal
{
public string Name { get; set; }
public string Bark { get; set; }
}

我能够订阅IAnimal接口,并接收CatDog这个两个类:

bus.Subscribe<IAnimal>("polymorphic_test",
@interface =>
{
var cat = @interface as Cat;
var dog = @interface as Dog; if (cat != null)
{
Console.WriteLine("Name = {0}", cat.Name);
Console.WriteLine("Meow = {0}", cat.Meow);
}
else if (dog != null)
{
Console.WriteLine("Name = {0}", dog.Name);
Console.WriteLine("Bark = {0}", dog.Bark);
}
else
{
Console.WriteLine("message was not a
dog or a cat");
}
}
);

让我们发布CatDog

var cat = new Cat
{
Name = "Gobbolino",
Meow = "Purr"
}; var dog = new Dog
{
Name = "Rover",
Bark = "Woof"
}; bus.Publish<IAnimal>(cat);
bus.Publish<IAnimal>(dog);

注意:必须显示的指定发布了IAnimal接口。EasyNetQ在发布和订阅方法中指定了泛型去发布和订阅。


为了能够支持消息版本控制,你需要确保这个必要的组件已配置。最简单的实现是这样的:

var bus = RabbitHutch.CreateBus("host=localhost",
services => services.EnableMessageVersioning());

一旦消息版本功能启动,你必须显示的选择你要版本化的消息加入版本控制。

// 这个消息不是被版本化的, 当这个消息被发布时,将和其他消息用同样发布去处理。
public class MyMessage
{
public string Text { get; set; }
} // 这个消息是版本化过的。对于订阅者有两种消息,MyMessageV2和MyMessage
public class MyMessageV2 : MyMessage, ISupersede<MyMessage>
{
public int Number { get; set; }
}

它是怎么工作的?

当你发布一个消息,EasyNetQ通常为这个消息类型创建一个交换机,然后发布这个消息到这个交换机。订阅者创建队列,绑定到这个交换机,因此可以接收任何发布到这个交换机上的消息。

当版本化的消息启用时,EasyNetQ将为每一个继承结构的版本化消息类型创建一个交换机,然后绑定这些交换机在一起。当你发布MyMessageV2消息时,这个消息被发送到MyMessageV2交换机上,并自动向上转发到MyMessage交换机。

当消息被序列化时,EasyNetQ会存储这个消息类型名称到这个消息的Type属性中。这个元数据会连同消息一起发送到任何订阅者,订阅者然后能够用这个元数据来反序列化这个消息。

当版本化消息启用时,EasyNetQ也将存储所有被取代的消息类型到这个消息Header属性中。订阅者将用这个属性查找第一个可用的消息类型去序列化,就算终结点没有最新版本的消息,只要有一个版本,它就能够被反序列化和被处理。

消息版本化指南

  1. 如果不能通过扩展原始消息类型去实现,那么它就不是一个新版本的消息。它是一个新的消息类型。
  2. 如果你不确定,宁可去创建一个新的消息类型,而不是去版本化一个已存在的肖。
  3. 被版本化的消息,不应该在Request/Response中做为消息类型去使用,RequestResponse是不同的,即使V2扩展与V1也是不同的。
  4. 版本化的消息不应用于Send/Receive,因为这是有针对性的发送,因为发送者和接受者之间是有依赖的。

反之

  1. 版本化消息支持已经在发布-订阅场景中被开发和测试过。它没有在send-receive 或者 request-response场景中被测试过。在发布-订阅之外其他模式中,风险自负。
  2. 版本化消息支持这个时候还没有扩展到未来的publish场景下。额外的工作已经计划开启了,但是由于潜在的中断可能发生,项目所有者和社区需要一些必要的讨论。
 

EasyNetQ使用(六)【多态发布和订阅,消息版本控制】的更多相关文章

  1. RBMQ发布和订阅消息

    RBMQ发布和订阅消息 exchange 参考翻译自: RabbitMQ官网 生产者并非将消息直接发送到queue,而是发送到exchange中,具体将消息发送到特定的队列还是多个队列,或者是丢弃,取 ...

  2. EasyNetQ之多态发布和订阅

    你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...

  3. 【EasyNetQ】- 多态发布和订阅

    您可以订阅接口,然后发布该接口的实现. 我们来看一个例子.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name { get ...

  4. Redis的高级应用-事务处理、持久化、发布与订阅消息、虚拟内存使用

    三.事务处理 Redis的事务处理比较简单.只能保证client发起的事务中的命令可以连续的执行,而且不会插入其他的client命令,当一个client在连接 中发出multi命令时,这个连接就进入一 ...

  5. 11-EasyNetQ之多态发布和订阅

    你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...

  6. 【cartographer_ros】六: 发布和订阅路标landmark信息

    上一节介绍了陀螺仪Imu传感数据的订阅和发布. 本节会介绍路标Landmark数据的发布和订阅.Landmark在cartographer中作为定位的修正补充,避免定位丢失. 这里着重解释一下Land ...

  7. Redis 发布与订阅 消息

    基于Redis消息队列-实现短信服务化 1.Redis实现消息队列原理 常用的消息队列有RabbitMQ,ActiveMQ,个人觉得这种消息队列太大太重,本文介绍下基于Redis的轻量级消息队列服务. ...

  8. Kafka(分布式发布-订阅消息系统)工作流程说明

    Kafka系统架构Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和 ...

  9. JMS发布/订阅消息传送例子

    前言 基于上篇文章"基于Tomcat + JNDI + ActiveMQ实现JMS的点对点消息传送"很容易就可以编写一个发布/订阅消息传送例子,相关环境准备与该篇文章基本类似,主要 ...

随机推荐

  1. 20191029 牛客CSP-S提高组赛前集训营1

    前一个小时看这几道题感觉要爆零 A. 仓鼠的石子游戏 分析一下发现a[i]>1a[i]>1a[i]>1时后先手必输,a[i]=1a[i]=1a[i]=1时先手必赢 然后直接看1的个数 ...

  2. win32通用控件

    1.标准控件 可以在win32窗口程序中添加资源脚本来给程序添加标准控件: 具体操作为:新建资源脚本    ->在.rc文件中添加控件    ->给控件绑定事件:   常用的标准控件:   ...

  3. 批量清理harbor镜像

    #! /bin/bash # 通过Harbor提供的API来批量删除镜像,人工删除费时费力 # 经过测试发现,通过接口去删除时提供的是的标签,但实际上删除的时候通过的是镜像的IMAGE_ID,也就是说 ...

  4. 34 | 到底可不可以使用join?

    在实际生产中,关于 join 语句使用的问题,一般会集中在以下两类: 我们 DBA 不让使用 join,使用 join 有什么问题呢? 如果有两个大小不同的表做 join,应该用哪个表做驱动表呢? 今 ...

  5. 节点(node)操作

    一.节点的属性 节点值页面中的所有内容,包括标签.属性.文本 nodeType,节点类型:如果是标签,则是1:如果是属性.则是2:如果是文本,则是3 nodeName,节点名字:如果是标签,则是大写的 ...

  6. 差分约束 4416 FFF 团卧底的后宫

    /* 4416 FFF 团卧底的后宫  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 你在某日收到了 FFF ...

  7. NetworkX系列教程(7)-对graph进行分析

    小书匠Graph图论 graph构建完成后,对graph的连通等属性进行分析. 目录: 8.对图进行分析 8.1连通子图 8.2弱联通 8.3强连通 8.4子图 8.5条件过滤 注意:如果代码出现找不 ...

  8. PHP + CI框架 + AdminLITE权限管理系统

    源码地址:https://github.com/yangsphp/rbac-master

  9. Java核心复习—— ThreadLocal源码分析

    ThreadLocal,叫做线程本地存储,也可以叫做线程本地变量.ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量. 一.如何使用 class Acce ...

  10. 个人学习分布式专题(二)分布式服务治理之分布式协调技术Zookeeper

    分布式协调技术Zookeeper 2.1 zookeeper集群安装部署(略) 2.2 zookeeper的基本原理,数据模型 2.3 zookeeper Java api的使用 2.4 zookee ...