WCF知识点
Session被终止,对应的Service Instance也标识为可回收对象,
当客户端的代理被关闭时,对应的Service Instance也会消失
所以我们说client端表现出的Session实际上是对应的Instancing来实现的,现在采用PerCall的Instance Context Mode, Proxy的状态是不可能被保留的。如果现在我们把Instance Context Mode设为PerSession,运行结果将会如我们所愿
2 只有WsHttpBinding的安全(Security)或可靠会话(Reliable Session)开启的情况下,创建的信道才具有会话的特性,解决办法
<serviceBehaviors>
6: <behavior name="highConcurrencyBehavior">
7: <serviceThrottling maxConcurrentSessions="20" />
8: </behavior>
9: </serviceBehaviors>
3 WCF对服务的并发会话的限制给WCF客户端提出了一个要求,那就是在服务代理不再使用的情况下,应该及时将其关闭。基于服务代理对象的会话会随着服务代理的关闭而关闭。服务端在处理客户端请求的时候,如果当前并发的会话数量超过了所允许的范围,后续的请求将会被放入等待队列,以等待现有会话的结束。对于客户端来说,服务调用在允许的超时时限(默认1分钟)内还未接收到回复,则会抛出一个TimeoutException异常
4 而实际上,服务代理的关闭与否对于数据报信道来讲,没有任何意义
5 建了OrderCollection对象,并添加了10个Order对象,如果该对象被序列化,最终被序列化对象数量是多少呢?应该这样来算,OrderCollection对象本身算一个,每一个Order对象自身也算一个,Order对象具有4个属性,设置序列化的数量,
<behaviors>
<serviceBehaviors>
<behavior name="serializationLimitationBehavior">
<dataContractSerializer maxItemsInObjectGraph="51" />
</behavior>
</serviceBehaviors>
</behaviors>
6 服务代理的关闭与否对数据报信道没有影响
7 限流由ServiceThrottlingBehavior类定义,包括三个重要的属性: MaxConcurrentCalls、MaxConcurrentSessions、MaxConcurrentInstances,它们分别的默认值为16,10和26
8 数据报通道”是指通道内的所有消息都无关联的通道。使用数据报通道时,如果输入或输出操作失败,下一个操作通常不会受到影响,并且同一个通道可以重用。因此,数据报通道通常不会出错。
与其相反,“会话通道”是与另一个终结点有连接的通道。某一端会话中的消息总是与另一端的同一会话相关联。另外,会话的两个参与者必须商定,只有彼此的对话要求得到满足,才能认为该会话是成功的。如果他们无法商定,则会话通道可能会出错。
9 public partial class CnblogsWcfClient :IDisposable
02 {
03 void IDisposable.Dispose()
04 {
05 try { this.Close(); }
06 catch (CommunicationException e)
07 {
08 this.Abort();
09 }
10 catch (TimeoutException e)
11 {
12 this.Abort();
13 }
14 catch (Exception e)
15 {
16 this.Abort();
17 }
18 }
19 }
10 参考配置:
<netTcpBinding>
<binding name="netTcpBindConfig" closeTimeout="00:30:00"
openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="1000"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:01:00" enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<behavior name="JXSoft.JPlan.WCFService.Behavior" >
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
<serviceMetadata/>
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="6553600"/>
</behavior>
11
一般WCF默认很多绑定是使用安全的,一般不是Transport(TcpBinding)就是Message(WSHttpBinding)安全模式。 而且会对客户端启用身份验证。
<security mode="None">
<transport clientCredentialType="None"/>
<message clientCredentialType="None"/>
12 WCF中的接口不能使用静态方法,但可以在实现类中重新包装一层
13 http://blog.chinaitlab.com/html/30/104830-163124.html
14
两种方法
public static class Extensions
{
public static void CloseConnection(this ICommunicationObject myServiceClient)
{
if (myServiceClient.State != CommunicationState.Opened)
{
return;
}
try
{
myServiceClient.Close();
}
catch (CommunicationException ex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
}
catch (TimeoutException ex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
}
catch (Exception ex)
{
Debug.Print(ex.ToString());
myServiceClient.Abort();
throw;
}
}
}
还有一种就是在 WCFServiceClient 写一个Partial 类,然后继承IDispose
在Dispose 方法里面关闭。 然后在前端使用Using
15
在补充一点,如果将ServiceDebugBehavior(开启IncludeExceptionDetailInFaults开关),WCF服务仅仅会将一般的CLR Exception(非FaultException)进行封装。对于FaultException,将不会做任何操作。
16 一个会话服务, 首先 1 BINGING是能提供的 2 SessionMode 必须适应 3 PerSession必须,如果是PerCall则不适合。 4 不能有事务,还有就是必须有数据信道(security和reliableSession两者有一个配置了即可)
17 不要在数据契约中使用泛型。那样命名将会非常奇怪. 如果在操作契约上也没什么问题。