方法一:
如果您要创建两个单独的主机(即,一个用于 WCF 服务,一个用于“轮询”服务),那么您实际上只有一个选项可以让它们正常工作。
Windows 服务通信非常有限(没有服务端点的帮助,例如 WCF)。因此,如果您要在 Windows 服务中托管“轮询”服务,则无论如何都必须将其与 WCF 服务相结合。
然后将这两个服务一起托管在一个 Windows 服务中并通过手动实例化 WCF 主机并将“轮询”服务传递给构造函数是可行的。
protected override void OnStart(string[] args)
{
//...
// This would be you "polling" service that would start a background thread to poll the db.
var notificationHost = new PollingService();
// This is your WCF service which you will be "self hosted".
var serviceHost = new WcfService(notificationHost);
new ServiceHost(serviceHost).Open();
//...
}
这远非理想,因为您需要通过两个服务之间的事件进行通信,而且您的 WCF 服务必须在单例模式下运行才能手动实例化工作......所以这让你......
方法B:
如果您要在 WCF 服务中托管“轮询”服务,您将遇到许多问题。
- 您需要了解创建的“轮询”服务实例的数量。如果您的 WCF 服务已配置为为每个会话实例化,您可能会得到太多的“轮询”服务,而这最终可能会杀死您的数据库/服务器。
- 为避免第一个问题,您可能需要设置单例 WCF 服务,这可能会在不久的将来导致扩展问题,即一个 WCF 服务实例不足以处理连接请求的数量。
方法C:
鉴于方法 A 和 B 的缺点,最好的解决方案是托管两个独立的 WCF 服务。
- 这是您订阅/取消订阅/发布的常规服务。
- 这是您的带有订阅/取消订阅的轮询单例服务。
这个想法是,您的常规服务在收到订阅者后将打开与您的轮询服务的新连接或使用现有连接(取决于您如何配置会话)并等待回复。您的轮询服务是一项长期运行的 WCF 服务,它轮询您的数据库并将通知发布给其订阅者(即其他 WCF 主机)。
优点:
- 您可以放心,只有一项投票服务。
- 您可以扩展您的解决方案以在 IIS 中托管常规服务并在 Windows 服务中托管轮询服务。
- 两个服务之间的通信限制最小,并且不需要事件。
- 通过它们的接口相互依赖地测试每个服务。
- 服务之间的低耦合和高内聚(这就是我们想要的!)。
缺点:
- 更多的服务意味着更多的接口和合约需要维护。
- 更高的复杂性。