我的WPF应用程序中有几个WCF服务,我使用这种方法打开它们:
private void StartSpecificWCFService(IService service, string url, Type serviceInterfaceType)
{
ServiceHost serviceHost = new ServiceHost(service, address);
serviceHost.AddServiceEndpoint(serviceInterfaceType, new NetNamedPipeBinding(), url);
serviceHost.Open();
//sign to serviceHost.Faulted ??
_wcfServicesHolder.Add(serviceHost); //A dictionary containing all my services
}
服务属性是:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
服务是日志服务和事件服务,它们从其他进程获得许多调用。我使用namedpipes,因为它是最快的,并且进程在SAME计算机上运行。
我的问题是 - 我如何保持这些服务一直在上升?
在服务处于故障状态后,是否必须重新创建客户端(在不同的进程上)?或者它仍然可以在同一频道上播放消息?
我收到的例外是:
There was no endpoint listening at net.pipe://localhost/LoggingService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
答案 0 :(得分:1)
为什么服务具有InstanceContextMode = InstanceContextMode.Single
并发线程访问权限?服务是否具有某种内存中线程安全状态?如果没有,那么尝试重新考虑使用InstanceContextMode.PerCall
的服务可能是值得的。在配置WCF服务时,这应该是您的默认选择 - WCF主要是用于实现面向服务的体系结构的技术,并且使用PerCall
以外的模式违反了SO Design Principles的无状态原则。
为了支持这一点,如果你有InstanceContextMode.Single
的服务器端错误,这表明服务中出现了严重错误。您在服务中维护的任何状态都将丢失 - 客户不能指望重新连接并恢复正常。
无论您最终使用的InstanceContextMode
是什么,如果您的频道在一段时间内没有客户端与其连接,您的频道就会出现故障。通过TCP(或任何明确公开可靠会话的协议),您可以在可靠会话上指定不活动超时,但您没有使用管道的此类选项。
使用管道,使通道打开的时间超过配置的超时时间,将使通道出现故障,使其无效。如果您有兴趣在应用程序的生命周期内保持对服务开放的通道,则可以订阅通道故障事件,并重新创建代理。正如你所建议的那样 - 另一个选择是继续沿着频道进行轮询以使其保持活力。
答案 1 :(得分:1)
为了保持您的服务主机,请使用您的#2选项(订阅服务主机上的故障事件)。出现故障时,您需要中止servicehost,新建一个新实例,重新连接故障事件处理程序,然后打开服务主机。
关于这种情况的官方文档并不多,但这是一篇来自msdn博客的旧帖子,描述了你正在寻找的东西。
http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx
对于客户端,当所述频道出现故障时,还需要重新建立到服务器的频道。