我有自己的服务请求需要15秒才能完成服务。应该不是问题吧?我们实际上有一个服务端计时器,因此它最多需要 15秒才能完成。但是,客户端看到“连接被强制关闭”并自动(在System.Net层内 - 我通过打开诊断程序看到它)重试GET请求两次。
哦,顺便说一句,这是一个非SOAP情况(WCF 4 REST服务),因此中间没有任何SOAP内容。此外,我的客户端是一个程序,而不是一个浏览器。
如果我把时间缩短到5秒(我可以人为地做),重试就会停止,但我无法解释如何快速连接掉连接。默认情况下,HttpWebRequest.KeepAlive标志为true且未被修改,因此连接应保持打开状态。
重试的时间很有趣。它们在我们选择的任何超时(例如10,15秒或其他)结束时到来,所以客户端似乎只在得到第一个响应后做出反应。
另一件事:服务端有 no 指示问题。它运行得很好,但看到一个令人惊讶的(对我而言)重试客户端的请求。
我用谷歌搜索了这个问题然后空了。保持活动的标准超过100秒AFAIK所以我仍然感到困惑为什么客户端的行为方式 - 并且行为在System.Net层内,所以我不能单步执行它。
非常感谢任何帮助!
== Tevya ==
答案 0 :(得分:0)
更改您的服务,以便在关闭连接之前向客户端发送超时指示。
答案 1 :(得分:0)
由于某些配置选择,听起来像是一块硬件(路由器,防火墙,负载均衡器?)正在发送RST。
答案 2 :(得分:0)
我找到了答案,它几乎完全与超时无关。相反,该问题与使用响应数据的自定义序列化有关。 respose数据结构有一些动态出现的类型,因此无法通过正常的ASP.NET机制进行序列化。
要解决这个问题,我们创建一个XmlObjectSerializer对象,然后将其传递给要序列化为System.ServiceModel.Channels.Message.CreateMessage()
的对象。这里出了两件事:
CreateMessage()
方法不会立即序列化内容,但推迟序列化,直到稍后(可能只是及时)。 这两个因素共同导致服务器端无法捕获序列化失败,因为在用户编写的服务代码将控制权返回给WCF基础结构之前,实际上并未尝试序列化对象。
现在为什么看起来像是超时?好吧,事实证明,并非 all 返回的对象中包含了意外的对象类型。特别是,前N个对象没有。因此,当时间限制延长超过5秒时,第N + 1个对象确实引用了未知类型,并且包含在打破序列化的下载中。后来的测试证实,即使只有一个物体被传回,也可能发生失败。
解决方案是预处理对象,以便不引用任何意外类型。一切顺利。
== Tevya ==