.Net消息传递pub / sub模式

时间:2016-03-17 09:16:18

标签: c# .net design-patterns publish-subscribe

所以我有一个在NancyFx上运行的.Net应用程序(需要与平台无关)。 我要求在某个事件发生时(订阅)我需要发送通知。通知将实现此接口:

public interface INotification
{
    public void Notify();
}

这将有许多不同的实现,例如电子邮件,Pushbullet,Pushover等。

我正在努力解决的是如何实际实现这一点,以便在订阅时INotification的所有实现都会执行Notify()

任何人都可以指出我正确的方向。

我真的不想使用任何类型的外部队列,因为应用程序将在用户计算机上运行。

因此,应用程序是自托管的,客户端和服务器位于用户计算机上,并且它不与外​​界通信,它都是内部的。

3 个答案:

答案 0 :(得分:3)

对不起,我只想确保我找对你。你还没有写出确切的问题,所以我假设你被某些基础知识所困扰。我也会忽略NancyFX,我不知道,我认为如果它支持这种情况,你会在文档中找到它。

为了让客户知道某些事情发生了变化,您基本上只有3个选项:
(a)服务器上有旧事件列表,服务器在事件发生时更新它,客户端定期读取它们并调用它们发出Ping的“通知”! (b)每个客户端打开与服务器的连接并保持打开状态,服务器记住连接,当新的连接发生时,通过已打开的连接向所有客户端发送消息,客户端获取消息并调用他们的“通知” Ping! (c)客户端向服务器发送注册消息,它包含回调地址/端口/等,服务器存储。当事件发生时,服务器读取列表并向这些地址发送信息,客户端处理这些请求并根据请求调用其Notify

由于您使用“发布 - 订阅”字样,我认为您的意思是(C)。

对于此选项,关于通知,客户端/服务器的角色实际上是颠倒。在正常情况下,服务器向客户端公开API,客户端连接到它,发送请求,服务器处理它并返回一些响应。在这方面,双方必须这样做。客户端应用程序还必须向服务器公开可调用的API,以便在“事件”发生时,服务器可以连接到客户端的API并向他发送包含通知数据的请求。

现在,您如何构建API - 这取决于您。您可以使用一个Notify(string xmlizedOrJsonizedData)方法,可以使用参数Notify(string infotype, datetime, data)或许多方法NotifyEmal(...) NotifyBullet(...) ... - 在实施注册和订阅簿记后,您只需要服务器调用客户端的api正确的请求数据,就像客户端一直这样做一样。

现在编写所有这些并重新发明轮子是一项工作。有很多库已经可以做到了。我看了,我没有在NancyFx文档中找到任何关于它的内容。可能你可以用它来创建一个客户端api,就像你创建服务器端api一样,但是......有一个问题。

客户端和服务器端不同。

当客户端与服务器通信时,只有一个服务器要发送和收听。您可以以天真的方式进行,甚至可以阻止UI。当服务器发回通知时,可能有10000个客户端。你甚至不应该以天真的方式开始写它。循环使用那么多客户端并等到完成后可以完全冻结您的服务器,如果没有冻结,则会导致速度减慢和超时。此外,服务器在公共场所。客户不是。客户端通常位于NAT,防火墙以及所有其他有趣的事物之后,这些事物会从客户端 - > - > - >服务器传递流量,但可能会阻止其他方向的流量。最基本的例子是阻塞端口。服务器上的:80几乎总是通过防火墙,但客户端上的:80可能不可用,当客户端在:23122上打开其api时,它可能不会在防火墙上配置/路由器..除非你用upnp / etc处理它。

这就是为什么选择一个可以为你完成所有这些工作的库是很好的...抱歉,我现在不记得任何名字,检查谷歌的PublishSubscribe模式,或客户端通知或推送通知服务器端库。

这就是为什么发明了一种名为“WebSockets”的东西。这基本上是我在开始时谈到的选项(B)。这真的值得研究。订阅发布的整个概念也可以通过websocket实现对服务器/客户端api /接口的调用/响应,但它可以为您节省大量的工作和网络问题。

我找到了use Nancy and SignalR可能的信息,这可能是一个非常好的开始。

答案 1 :(得分:0)

如果侦听器将在同一个应用程序而不是远程服务中,您可能希望使用类似于应用程序内部的消息总线。我知道您可能没有使用WPF / MVVM,但框架MVVM light有一个消息总线的小示例实现。

但是出于特定目的,您可能希望找到一个与MVVM无关的示例,或者只是编写类似的内容。

答案 2 :(得分:0)

您可以使用.NET distributed cache as a publisher/subscriber媒介。 NCache提供了这样一种机制

基本上您将使用应用程序启动的自定义事件

注册您的活动

public void OnApplicationEvent(object notifId, object data)
{
  ...
} 
_cache.CustomEvent += new CustomEventCallback(this.OnApplicationEvent);

并在需要时点击这些事件

_cache.RaiseCustomEvent("NotificationID", DateTime.Now);