一个基于.net的消息总线
降低程序(特别是cs程序)各个类之间的耦合度,在上位机开发中常常会遇到某一个page(form)调用另外一个page的功能,这样会出现多个page之间的引用,而且当一组数据产生多出影响或者行为的时候,大大降低了多个page之间的耦合。
NuGet\Install-Package iml6yu.MessageBus -Version 1.0.0-release230626001
dotnet add package iml6yu.MessageBus --version 1.0.0-release230626001
MessageBuses.Subscrib
Subscrib方法返回一个订阅者对象,通过关联对象的OnNoticed事件触发。
public class MyClass1
{
}
MessageBuses.Subscrib().OnNoticed += Form2_OnNoticed;
private void Form2_OnNoticed(MessageChannel arg1, MessageBusArges arg2)
{
this.Invoke(new Action(() => { MessageBox.Show(arg2.Data.ToString()); }));
}
MessageBuses.Publish(new MyClass1());
订阅和发布都可以通过Channel进行,使用泛型方法默认不指定channel的时候,通道名是该类型的FullName
MessageBuses.Publish(new MyClass1());
ISubscriber subscriber;
subscriber = MessageBuses.Subscrib("newWin");
subscriber.OnNoticed += (channel,e)=>{
Debug.WriteLine(e.Data.ToString())
};
发布/订阅者模式的优点
发布/订阅者模式的优点可以归纳为:
松耦合/Independence
发布/订阅者模式可以将众多需要通信的子系统(Subsystem)解耦,每个子系统都可以独立管理。而且即使部分子系统下线了,也不会影响系统消息的整体管理。
发布/订阅者模式为应用程序提供了关注点分离。每个应用程序都可以专注于其核心功能,而消息传递基础结构负责将消息路由到每个消费者手里。
高伸缩性/Scalability
发布/订阅者模式增加了系统的可伸缩性,并提高了发送者的响应能力。原因是发送方(Publisher)可以快速地向输入通道发送一条消息,然后返回到其核心处理职责,而不必等待子系统处理完成。然后消息传递的基础结构负责确保把消息传递到每个订阅者(Subscriber)手里。
高可靠性/Reliability
发布/订阅者模式提高了可靠性。异步的消息传递有助于应用程序在增加的负载下继续平稳运行,并且可以更有效地处理间歇性故障。
灵活性/Flexibility
你不需要关心不同的组件是如何组合在一起的,只要他们共同遵守一份协议即可。
发布/订阅者模式允许延迟处理或者按计划的处理。例如当系统负载大的时候,订阅者可以等到非高峰时间才接收消息,或者根据特定的计划处理消息。
可测试性/Testability
发布/订阅者模式提高了可测试性。通道可以被监视,消息可以作为整体集成测试策略的一部分而被检查或记录。
实现发布/订阅者模式需要考虑的点
订阅处理
订阅者可以在消息通道中订阅或者取消订阅某个话题。
安全
连接到任何消息通道必须受到安全策略的限制,以防止未经授权的用户或应用程序窃听。
内容筛选
根据每条消息的内容检查和分发消息。每个订户都可以指定其感兴趣的内容。
订阅者通常只对发布者分发的消息的子集感兴趣。消息服务通常允许订户缩小以下用户接收到的消息集。
考虑允许订户通过通配符订阅多个主题。每个主题都有一个专用的输出通道,每个使用者都可以订阅所有相关主题。
双向通信
发布订阅系统中的通道被视为单向的。
如果特定订户需要向发布服务器发送确认或通信状态,请考虑使用请求/回复模式。此模式使用一个通道向订阅服务器发送消息,以及一个单独的回复通道向发布服务器进行通信。
消息排序
使用者实例接收消息的顺序不一定得到保证,也不一定反映消息的创建顺序。
设计该系统以确保消息处理是等量的,以帮助消除对消息处理顺序的任何依赖。
消息优先级
有些解决方案可能需要按特定顺序处理消息。优先级队列模式提供了一种确保特定消息先于其他消息传递的机制。
有毒信息
格式错误的消息或需要访问不可用资源的任务可能会导致服务实例失败。系统应防止此类消息返回到队列,否则可能导致系统故障。
消息重复
同一消息可能会发送多次。例如,发送者可能在发布消息后出现了异常,没有记录自己已经成功发送了消息,然后,发送者的新实例可能会启动并重复该消息。
消息基础结构应基于消息ID实现重复消息检测和删除(也称为重复数据消除),以便最多提供一次消息传递。
消息过期
消息的生命周期可能有限。如果在这段时间内没有处理,它可能不再有价值,应该丢弃。发送方可以指定过期时间作为消息中数据的一部分。在决定是否执行与消息关联的业务逻辑之前,接收者可以检查此信息,以确保消息没有过期。
消息调度
例如,消息可能会被暂时禁止,直到特定的日期和时间才被处理。
何时应使用发布/订阅者模式
如果你的程序只有很少的订阅者,或者需要与子系统进行实时的交互,那么发布/订阅者模式是不适合的。
在以下情况下可以考虑使用此模式:
应用程序需要向大量消费者广播信息。例如微信订阅号就是一个消费者量庞大的广播平台。
应用程序需要与一个或多个独立开发的应用程序或服务通信,这些应用程序或服务可能使用不同的平台、编程语言和通信协议。
应用程序可以向消费者发送信息,而不需要消费者的实时响应。
被集成的系统被设计为支持其数据的最终一致性模型。
应用程序需要将信息传递给多个消费者,这些消费者可能具有与发送者不同的可用性要求或正常运行时间计划。例如你消息在上午发布了出去,消费者计划在下午才去处理这些消息。