如何使用 WCF 从 Windows 服务通知应用程序



我有一个从串行端口连续读取数据的 Windows 服务,我希望能够从该服务使用 WCF 通知 WPF 应用程序更新的数据;我想过使用回调。

Windows 服务将调用

WCF 服务的方法,而该方法又将调用 WPF 应用程序回调:

[ServiceContract(CallbackContract = typeof(IUpdateCallback))]
public interface IMyService
{
     [OperationContract]
     void Update(UpdatedData data);
}
public interface IUpdateCallback
{
    void OnUpdate(UpdatedData data);
}

这就是我计划实现该服务的方式:

public class MyService : IMyService
{
    public void Update(UpdatedData data)
    {
        var callback =  OperationContext.Current.GetCallbackChannel<IUpdateCallback>();
        callback.OnUpdate(data);
    }
}

然后从客户端应用程序方面:

public class UpdateCallback : IUpdateCallback
{
    public void OnUpdate(UpdatedData data)
    {
        // Update data logic...
    }
}

我是否走在正确的轨道上,或者有更好的方法来做到这一点?

因此,使用回调当然是执行此操作的一种方法。但是,回调通道可能会超时,因此您需要一种自动重新连接的方法。如果你想继续沿着这条路走下去,那么你在理解方面看起来很好。

在我看来,一个更简单(因此更优越)的解决方案是使用 netMsmqBinding,在 WPF 应用程序中托管服务,然后让 Windows 服务使用它。这样做的好处是它比双工通信更可靠,因为它依赖于单向调用,并且更容易实现。

此外,即使 WPF 不可用,Windows 服务仍将能够向 WPF 应用发送通知 - 消息将只是排队,直到 WPF 重新联机。(这可能是可取的,也可能是不可取的。

您需要在两台计算机上启用 msmq,并且为了获得最大可靠性,请使用带有 DTC 的事务队列。

如果我希望能够将数据从客户端应用程序发送到串行 端口(Windows 服务仍将处理 IO),我是否必须 实现另一个 WCF 服务

在这种情况下,是的,您必须在 Windows 服务上配置一个服务,该服务公开了 WPF 要调用的操作。这需要与用于通知的单独定义,并且可以仅使用 http/tcp 作为传输而不是消息队列,因为这听起来像是同步操作。

我是否应该在 WPF 项目中定义 WCF 服务,而不是 独立 DLL?

WPF 项目是 WCF 服务的宿主进程。从这个角度来看,如果将服务定义为独立程序集或在 WPF 应用中定义,则应该能够在 WPF 应用中启动一个将公开服务的ServiceHost实例,这没有什么区别。

尽管将服务代码定义为服务的运行时托管几乎没有区别,但作为最佳实践,我总是尝试将实际的服务实现定义为单独的程序集,以将逻辑上不同的内容保留在不同的位置。

我应该如何使用来自 WPF 应用程序的数据: Windows 服务将调用 WCF 服务并从此处发送数据 我需要检索保存在某处的数据

因此,我的理解是,您最初的计划是在从串行端口读取数据的 Windows 服务承载 WCF 服务。

然后,WPF 服务将调用 WCF 服务,

WCF 服务将存储 WPF 服务的回调委托,实际上类似于订阅。

当数据到达串行端口时,WCF 服务将调用回调通道并将数据反馈给 WPF 服务。

我的建议是将其替换为基于队列的方法,在该方法中,您将在 WPF 应用程序中承载服务,并让 Windows 服务在数据到达串行端口时仅调用 WCF 服务。

然后,你询问了是否还要让 WPF 应用调用 Windows 服务来传递数据,我说你应该在 Windows 服务中托管一个单独的服务,以便公开要调用的 WPF 应用的终结点。当 WPF 应用进行调用并将数据传递到 WCF 服务时,此数据可用于与串行端口通信的 Windows 应用程序。

您现在是否在询问如何允许从 WPF 应用传递到 Windows 服务承载的 WCF 应用的调用中的数据可用于 Windows 服务?如果是这样,请阅读我的文章,其中详细介绍了如何将数据从 WCF 服务的实例传递到运行 ServiceHost 实例的应用程序域。

MSMQ是处理此问题的好方法。如果您的技术堆栈允许,我会检查ActiveMQ或RabbitMQ,因为您可以将数据进行真正的发布/订阅广播到有兴趣接收这些事件的其他应用程序。

最新更新