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

时间:2015-03-09 15:23:10

标签: c# wcf windows-services ipc

我有一个连续从串口读取数据的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);
    }
}

然后从客户端App方面:

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

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

2 个答案:

答案 0 :(得分:2)

所以使用回调肯定是这样做的一种方式。但是,回调通道可能会超时,因此您需要一种自动重新连接的方法。如果你想继续沿着这条路走下去,那么你看起来很明智。

在我看来,一个更简单(因此更优越)的解决方案是使用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服务使用?如果是,那么请阅读我的帖子here,其中详细说明了如何将数据从WCF服务的实例传递到运行ServiceHost实例的应用程序域。

答案 1 :(得分:0)

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