2

我需要通知 1 多个客户端执行任务(重新加载)。服务器可能在也可能不在任何给定时间点运行。(出于这个原因,我很难定义谁是客户端,谁是服务器。)

在任何给定时间,服务器都可以开始运行。当服务器自行关闭时,它会通知所有客户端执行他们的任务。

我尝试NamedPipeServerStream在“客户端”上使用并运行多个实例(记住这种关系很奇怪,所以请耐心等待)。不幸的是,我只能为任何给定的服务器名称创建一个管道服务器。所以这没有用。我可以让客户端不断检查服务器,但如果我要开始轮询,那么我不妨直接轮询数据库。

我的情况大致类似于观察者模式。我不需要动态订阅/取消订阅。我确实希望服务器向所有正在运行的客户端推送通知以执行任务。

我怎样才能做到这一点?请记住,我必须使用 IPC 执行此操作。服务器/客户端在不同的进程下运行,并且始终在同一台机器上。

4

3 回答 3

3

要解决轮询问题,您可以创建一个名为 ManualResetEvent 的客户端进程将侦听。客户端将启动一个线程然后等待事件,当服务器启动时,它将发出事件信号并让所有客户端启动他们的监听代码,该代码可以像你现在一样打开一个命名管道。查看EventWaitHandle.GetAccessControl MSDN 页面,了解如何创建已命名的 ManualResetEvent 的示例。

对于您的I can only create one Pipe server for any given server name.问题,如果有多个服务器正在运行,客户端应该如何知道要连接到哪个服务器?你说这是一个服务器到*客户端的关系。如果您要运行多个服务器,您将需要一种方法来告诉客户端它应该监听哪个服务器。

于 2012-02-17T15:32:10.757 回答
1

因为您指定所有进程都保证在同一台机器上,所以我可能会考虑使用名为 event的 Windows 。您的客户端和服务器可以调用OpenEvent,如果尚未创建事件,请调用CreateEvent。这将使您能够对每个事件释放多少客户端进行一些控制(使用脉冲事件、设置/重置等),并且还允许您在没有服务器的情况下打开客户端。

正如 Scott 建议的那样,要在 c# 中轻松执行此操作,请使用名为 .net 的 .net EventWaitHandle,方法是调用带有字符串的构造函数(例如this one)。这将为您创建系统范围的同步对象。该特定构造函数还将告诉您是否是第一个请求事件(您创建它),或者它已经存在。

于 2012-02-17T15:33:37.140 回答
0

使用命名共享内存是完成一对多通信的一种方式。服务器可以创建共享内存,一个或多个客户端可以打开它并读取它。 此处显示了一个示例(在 C 中)。此外,此处显示了一个 .NET 示例

只要至少有一个进程有一个打开的句柄,共享内存就会存在。从 OP 看来,这听起来像是一个有用的功能,因为即使在服务器进程关闭后内存也可以继续存在(只要至少有一个客户端仍然打开它)。.NET 示例还展示了如何保存信息,如果它必须比进程更有效,这将很有用。

根据所需的时间,客户端可以定期读取内存以获取必要的信息。或者,如果存在时间更紧迫的情况,您可以使用命名信号量来向客户端发出信号以执行必要的操作。使用信号量作为同步对象,您可以通过将释放计数设置为大于 1 的值来向多个客户端发出信号。

于 2012-02-17T15:29:09.400 回答