【发布时间】:2012-11-30 02:22:51
【问题描述】:
最终 WCF 双工 Silverlight 4 客户端开始收到 404 Not Found 轮询消息错误,轮询从 WCF 服务发送到 Silverlight 客户端后,有时会发生第二次轮询,有时连接工作数小时甚至数天,但第一次大多失败分钟。
!有趣的是,当使用MaxMessagesPerPollduplex 模式和解决方案描述为here 和here 时,这个问题就像已知的Silverlight 4 错误,但我使用的是SingleMessagePerPoll 模式。无论如何,我按照建议尝试使用ClientStack,但没有任何改变。
一般流程:
- SL 客户端执行 WCF 服务方法,收到响应
- 然后立即 SL 客户端开始向服务发送轮询消息,然后获取第二个或 N-s 轮询消息的异常
System.Net.WebException:远程服务器返回错误:NotFound
- Fiddler 仅显示空的
404对投票消息的响应 - 然后引发客户端 Channel Faulted 事件
我正在尝试在出现此类故障后重新连接 SL 客户端,单次重新连接重试流程:
- 处理
Faulted事件 - 取消订阅所有频道事件,例如
Closed/Closing/Opened/Opening - 使用
try { close } catch { abort }以正确的方式关闭频道 - 下面的所有内容都在一个新的线程轮询线程中:(我发现这有点稳定 - see this article)
- 等待 45-70 秒
- 使用相同的
DuplexChannelFactory<T>实例创建一个新频道,订阅所有频道事件,仅用于记录目的 - 执行 WCF 服务方法
在重试 1-10 次(约 1-10 分钟)后,客户端最终连接到服务器并继续正常轮询。
在 WCF 服务日志中,我看到它得到了所有客户端请求,没有任何异常处理,所以 Silverlight 客户端似乎发生了一些事情。
一般信息:
- .NET Framework 4.0
- 轮询双工
- 异步 WCF 方法
- IIS 6.0 托管的 WCF 服务
- Silverligth 4 客户端
- 客户端操作系统:Windows XP SP2
- 服务器操作系统:Windows 2003 R2 SP2
- NTLM 身份验证
- 双工模式:SingleMessagePerPoll
- 还有一个 WCF 服务在我的服务开始工作之前执行请求/回复,它不使用双工连接
- 在 SL 客户端服务上,我将所有内容都记录到 UI 中,以便查看所有事件流并为每个特定事件留出时间
- IIS 日志、服务器事件日志中没有错误
客户:
var binaryBinding = new BinaryMessageEncodingBindingElement();
binaryBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
var httpbindingElement = new HttpTransportBindingElement
{
MaxReceivedMessageSize = 131072
};
var pollingDuplexBindingElement = new PollingDuplexBindingElement
{
ClientPollTimeout = new TimeSpan(0, 0, 1, 30),
InactivityTimeout = new TimeSpan(0, 8, 0, 0),
};
_binding = new CustomBinding(
pollingDuplexBindingElement,
binaryBinding,
httpbindingElement)
{
SendTimeout = new TimeSpan(0, 0, 0, 45),
CloseTimeout = new TimeSpan(0, 0, 0, 25),
ReceiveTimeout = new TimeSpan(0, 8, 0, 0),
OpenTimeout = new TimeSpan(0, 0, 0, 45)
};
httpbindingElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
var endpoint = new EndpointAddress(_endpointAddress);
_channelFactory = new DuplexChannelFactory<TWebService>(
new InstanceContext(instanceOfClientServiceClass),
_binding,
endpoint);
// then this factory used to create a new channels
// Also for a new channel I'm setting OpTimeout
var contextChannel = newChannel as IContextChannel;
if (contextChannel != null)
{
contextChannel.OperationTimeout = TimeSpan.FromSeconds(45);
}
服务器:
- WCF、PerSession、多线程
- 一切都是线程安全的
- 执行时没有服务器服务异常
- 大量日志记录,所以我可以看到服务上发生了什么
- 所有 WCF 跟踪都使用 switchValue
All启用,没有任何可疑之处
<binding name="customName"
sendTimeout="00:01:00"
receiveTimeout="08:00:00"
openTimeout="00:01:00"
closeTimeout="00:00:35">
<pollingDuplex
inactivityTimeout="08:00:00"
serverPollTimeout="00:01:00" />
<binaryMessageEncoding />
<httpTransport authenticationScheme="Ntlm"
maxReceivedMessageSize="131072">
</httpTransport>
</binding>
<behavior name="customBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling
maxConcurrentCalls = "500"
maxConcurrentSessions = "500"
maxConcurrentInstances = "500" />
</behavior>
【问题讨论】:
-
谢谢,但似乎不是我的情况,我没有使用 SSL,我的服务有时在没有 404 的情况下工作了一天,但有时即使 10 分钟也无法正常工作
标签: .net wcf silverlight polling pollingduplexhttpbinding