我有一个相当简单的 WCF 服务,它为一堆智能客户端执行单向文件同步。我注意到,当通话期间出现网络或服务中断时,客户端将无法与服务器通信,直到整个应用程序重新启动。
该服务运行于BasicHttpBinding
并由 IIS6(一个 .svc 页面)托管,使用transferMode="Streamed"
and messageEncoding="Mtom"
。该服务配置为使用默认的 InstanceContextMode (我认为是 Per Call?)和 ConcurrencyMode=Single。它使用默认的限制行为,但我处于一个没有其他人访问的隔离测试环境中。
客户端是Windows 服务。我正在用这个服务代理助手 http://bloggingabout.net/blogs/erwyn/archive/2006/12/09/WCF-Service-Proxy-Helper.aspx以确保连接Close()
'd or Abort()
正确时Dispose()
d,虽然没有会议,所以我认为这并不重要。当发生错误时,Client 对象将被释放,然后超出范围。检测到异常后,服务会等待一段时间,然后创建一个新的客户端对象并重试。因此它应该从故障中恢复,但由于某种原因,所有后续对该服务的调用都会失败。
我可以通过启动客户端、允许它传输一些文件,然后重置服务器来可靠地重现这一点。首先,客户端通常会显示“服务太忙”错误(该错误映射到应用程序重新启动期间收到的 IIS 503 错误)。此后,所有后续对该服务的调用都会超时。据我所知,客户甚至没有尝试拨打电话。我启用了跟踪,我看到的是:超时错误,然后是“无法通过 HTTP 发送请求消息”警告,然后是另一个超时错误。
疯狂的是,当我在 app.config 中将客户端配置为使用 Fiddler(端口 8888)作为代理时,一切都按预期工作。因此,Fiddler 作为代理正在以某种方式关闭或完成某种类型的连接,而 WCF 本身则不会。
想法?
编辑 2009-10-30 8:54PM:将服务属性更改为:InstanceContextMode=Single 和 ConcurrencyMode=Multiple。没有不同。
嗯,那很痛苦。我花了很长时间,但最后我集中精力在使用代理运行与不使用代理运行之间的区别,并开始研究<system.net>
设置。事实证明,向客户端添加此配置位可以解决问题:
<system.net>
<settings>
<servicePointManager expect100Continue="false" />
</settings>
</system.net>
有人可以解释一下发生了什么事吗?为什么此设置会导致 WCF 客户端在服务中断时无法修复地挂起?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)