为长时间运行的WCF应用程序选择正确的连接属性
我正在使用WCF用C#编写一个客户机/服务器应用程序。我的所有测试都进行得很顺利,但在部署服务后,我发现在与服务器通信时出现了随机问题。 我启用了调试,并在服务器中看到如下消息:为长时间运行的WCF应用程序选择正确的连接属性,wcf,wcf-binding,wcf-client,Wcf,Wcf Binding,Wcf Client,我正在使用WCF用C#编写一个客户机/服务器应用程序。我的所有测试都进行得很顺利,但在部署服务后,我发现在与服务器通信时出现了随机问题。 我启用了调试,并在服务器中看到如下消息: The communication object, System.ServiceModel.Channels.ServerReliableDuplexSessionChannel, cannot be used for communication because it has been Aborted. 模式如下:
The communication object, System.ServiceModel.Channels.ServerReliableDuplexSessionChannel, cannot be used for communication because it has been Aborted.
模式如下:
- 客户端正在发送查询
- 服务正在处理查询
- 服务正在发回一些东西
- 活动边界为“停止”级别-一切正常
- 将inactivityTimeout of reliable session添加到最后一个联系人的datetime,您就有了服务引发的异常的时间戳
[ServiceContract(CallbackContract = typeof(ISVCCallback), SessionMode = SessionMode.Required)]
[ExceptionMarshallingBehavior]
...
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<serviceMetadata httpGetEnabled="false" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="1000"
maxConcurrentInstances="50" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transferMode="Buffered"
listenBacklog="1000" maxBufferPoolSize="671088640" maxBufferSize="671088640"
maxConnections="1000" maxReceivedMessageSize="671088640" portSharingEnabled="true">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession inactivityTimeout="23:59:59" enabled="true" />
<security mode="None">
</security>
</binding>
</netTcpBinding>
</bindings>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ISVC" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="1000"
maxBufferPoolSize="671088640" maxBufferSize="671088640" maxConnections="1000"
maxReceivedMessageSize="671088640">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession ordered="true" inactivityTimeout="23:59:59"
enabled="true" />
<security mode="None">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
及
服务配置:
[ServiceContract(CallbackContract = typeof(ISVCCallback), SessionMode = SessionMode.Required)]
[ExceptionMarshallingBehavior]
...
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<serviceMetadata httpGetEnabled="false" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="1000"
maxConcurrentInstances="50" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transferMode="Buffered"
listenBacklog="1000" maxBufferPoolSize="671088640" maxBufferSize="671088640"
maxConnections="1000" maxReceivedMessageSize="671088640" portSharingEnabled="true">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession inactivityTimeout="23:59:59" enabled="true" />
<security mode="None">
</security>
</binding>
</netTcpBinding>
</bindings>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ISVC" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="1000"
maxBufferPoolSize="671088640" maxBufferSize="671088640" maxConnections="1000"
maxReceivedMessageSize="671088640">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession ordered="true" inactivityTimeout="23:59:59"
enabled="true" />
<security mode="None">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
客户端配置:
[ServiceContract(CallbackContract = typeof(ISVCCallback), SessionMode = SessionMode.Required)]
[ExceptionMarshallingBehavior]
...
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<serviceMetadata httpGetEnabled="false" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="1000"
maxConcurrentInstances="50" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transferMode="Buffered"
listenBacklog="1000" maxBufferPoolSize="671088640" maxBufferSize="671088640"
maxConnections="1000" maxReceivedMessageSize="671088640" portSharingEnabled="true">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession inactivityTimeout="23:59:59" enabled="true" />
<security mode="None">
</security>
</binding>
</netTcpBinding>
</bindings>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ISVC" closeTimeout="00:01:00" openTimeout="00:10:00"
receiveTimeout="23:59:59" sendTimeout="00:01:30" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="1000"
maxBufferPoolSize="671088640" maxBufferSize="671088640" maxConnections="1000"
maxReceivedMessageSize="671088640">
<readerQuotas maxStringContentLength="671088640" maxArrayLength="671088640"
maxBytesPerRead="671088640" />
<reliableSession ordered="true" inactivityTimeout="23:59:59"
enabled="true" />
<security mode="None">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
这里有什么问题吗?这类应用程序的最佳配置是什么
更新:
我遇到了一件事:
在一个服务合同中,我更改了一些内容并通知所有连接的客户端。它通常运行良好,至少在我的测试中是这样。但上一次“崩溃”或“冻结”我浏览了日志,发现最新的函数是我使用回调契约通知客户机的函数
我想在那里做的是:我将一些东西保存到数据库中,最后我将更改通知所有连接的客户端。我认为连接的客户端列表不再是最新的,在这一步它会超时
现在的问题是如何避免这些超时
- 我应该在服务中使用线程吗?我想一旦服务调用结束,线程就会被终止,对吗
- 我可以实现一个静态队列函数,它执行所有回调通知(这是Marc_建议的)
- 有没有一种方法可以可靠地检测服务器内部的连接断开
- 您不需要非常脆弱和复杂的回拨合同设置
- 您的系统已解耦,即使它们之间的连接中断几秒钟、几分钟、几小时,也将继续工作
- 您的服务可以响应传入的消息并发送更多“目标”响应,例如,某些客户端可以在“正常”响应队列上侦听,其他客户端可以在“优先级”响应队列上侦听,等等。系统只会为您提供更大的灵活性
- -留言
public enum CallbackType
{
callbackfunc1,
callbackfunc2,
callbackfunc3
};
public class CallbackEventArgs : EventArgs
{
public ISVCCallback callback;
public CallbackType type;
public string s1;
public string s2;
public string s3;
public List<string> ls1;
}
// Declare delegate
public delegate void SVCEventHandler(object sender, CallbackEventArgs e);
谢谢 嗨,马克,非常感谢你的回答。不幸的是,这个项目已经完成了98%,我只剩下2周的时间来实现缺少的东西。抛弃当前的体系结构,采用另一种方法在此时听起来并不正确。不幸的是,我现在必须用WCF解决这个问题,然后可能会在版本2.0中重新设计架构。我希望你们能给我这个问题的答案。起初我认为WCF正是为这类东西而设计的……是的,当然——WCF很棒,而且非常灵活。它还支持MSMQ消息传递!回调合同的内容有时有点“脆弱”,不一定是WCF的错,只是很难做到。