Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .Net消息发布/订阅模式_C#_.net_Design Patterns_Publish Subscribe - Fatal编程技术网

C# .Net消息发布/订阅模式

C# .Net消息发布/订阅模式,c#,.net,design-patterns,publish-subscribe,C#,.net,Design Patterns,Publish Subscribe,因此,我有一个运行在NancyFx上的.Net应用程序(需要与平台无关)。 我有一个要求,当某个事件发生时,我需要发送一个通知(订阅)。通知将实现此接口: public interface INotification { public void Notify(); } 这将有许多不同的实现方式,例如电子邮件、Pushbullet、Pushover等 我正在努力解决的是如何实际实现这一点,以便在有订阅时,所有INotification的实现都将执行Notify() 谁能给我指一下正确的方

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

public interface INotification
{
    public void Notify();
}
这将有许多不同的实现方式,例如电子邮件、Pushbullet、Pushover等

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

谁能给我指一下正确的方向吗

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


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

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


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

请稍等,我只想确保您的理解正确。你还没有写下确切的问题是什么,所以我假设你在一些基础知识上有困难。我也会忽略NancyFX,我不知道,我假设如果它支持这个案例,你会在文档中找到它

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

既然你用了“发布-订阅”这个词,我想你的意思是(C)

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

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

现在写下所有这些并重新发明轮子需要一些工作。有很多图书馆已经可以做到这一点。我看了看,在NancyFx的文档中没有找到任何关于这方面的信息。也许您可以使用它来创建客户端api,就像创建服务器端api一样,但是。。有一个陷阱

客户端和服务器端不同

当客户机与服务器对话时,只有一台服务器要发送和侦听。你可以用天真的方式来做,如果你喜欢的话,甚至可以阻塞UI。当服务器发回通知时,可能有100000个客户端。你甚至不应该开始用一种天真的方式来写它。在这么多客户端上循环并等待完成可能会完全冻结服务器,如果不冻结,则会导致速度减慢和超时。此外,服务器是公开的。客户并非如此。客户端通常位于NAT、防火墙和所有其他有趣的东西后面,这些东西将流量从客户端->传递到->服务器,但可能会阻止另一个方向的流量。最基本的例子是阻塞端口<服务器上的code>:80几乎总是通过防火墙,但客户端上的
:80
可能不可用,当客户端在
:23122
上打开其api时,可能不会在其防火墙/路由器上进行配置。。除非你用upnp/等来处理

这就是为什么选择一个能为你做所有这些的图书馆是件好事。。很抱歉,我现在想不起任何名字,请检查例如google的PublishSubscribe模式、客户端通知或推送通知服务器端库

这就是为什么一种叫做“WebSocket”的东西被发明了。这就是我一开始提到的选项(B)。这确实值得调查。subscribe publish的整个概念也可以通过websocket实现为对服务器/客户端API/接口的调用/响应,但它为您节省了大量工作和网络问题

我发现了一个信息,这可能是一个很好的开始。

你可以使用媒体。 NCache提供了这样一种机制

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

注册您的活动

public void OnApplicationEvent(object notifId, object data)
{
  ...
} 
_cache.CustomEvent += new CustomEventCallback(this.OnApplicationEvent);
你需要的时候就把这些事件放了

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

你有关于如何写类似的东西的例子和建议吗?我想我的问题有很多含糊不清的地方,因为我不了解基础知识。对此我深表歉意。当你说客户机和服务器时,客户机和服务器都是在用户计算机内部托管的,它不会与外部世界通信。@JamieR:这很重要,请在你的问题中添加这一点,它会