您的位置:首页 > 其它

WCF客户端和服务端配置

2011-10-26 12:45 537 查看
 基于Http的双向通讯V.S.基于TCP的双向通讯

由于Http和TCP在各自协议上的差异,他们实现双向通信的发式是不同的。
Http是一个应用层的协议,它的主要特征就是无连接和无状态(connectless & stateless )。它采用传统的Request/Reply的方式进行通信,Client发送Http Request请求Server的某个资源,Server端接收到该Http Request, 回发对应的Http Response。当Client端接收到对应的Response,该Connection会关闭。也就是说Client和Server的Connection仅仅维持在发送Request到接收到Response这一段时间内。同时,每次基于Http的
connection是相互独立,互不相干的,当前connection无法获得上一次connection的状态。为了保存调用的的状态信息,ASP.NET通过把状态信息保存在Server端的方式实现了对Session的支持,具体的做法是:ASP.NET为每个Session创建一个Unique ID,与之关联一个HttpSessionState对象,并把状态信息保存在内存中或者持久的存储介质(比如SQL Server)中。而WCF则采用另外的方式实现对Session的支持:每个Session关联到某个Service
Instance上。
回到我们WCF双向通信的问题上,当Client调用Service之前,会有一个Endpoint在Client端被创建,用于监听Service端对它的Request。Client对Service的调用会建立一个Client到Server的Connection,当Service在执行操作过程中需要Callback对应的Client,实际上会建立另一个Service到Client的Http
connection。虽然我们时候说WCF为支持双向通信提供Duplex Channel,实际上这个Duplex channel是由两个Request/Reply Channel组成的。
而对于TCP/IP簇中的传输层协议TCP,它则是一个基于Connection的协议,在正式进行数据传输的之前,必须要在Client和Server之后建立一个Connection,Connection的建立通过经典的“3次握手”来实现。TCP天生就具有Duplex的特性,也就是说当Connection被创建之后,从Client到Sever,和从Server到Client的数据传递都可以利用同一个Connection来实现。对于WCF中的双向通信,Client调用Service,Service
Callback Client使用的都是同一个Connection、同一个Channel。所以基于TCP的Duplex Channel才是真正意义上的Duplex Channel。
 

WCF的配置是合理加强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(
b915
);

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中的接口不能使用静态方法,但可以在实现类中重新包装一层

还有一种就是在 WCFServiceClient 写一个Partial 类,然后继承IDispose

在Dispose 方法里面关闭。 然后在前端使用Using

 

13

在补充一点,如果将ServiceDebugBehavior(开启IncludeExceptionDetailInFaults开关),WCF服务仅仅会将一般的CLR Exception(非FaultException)进行封装。对于FaultException,将不会做任何操作。

 

14 一个会话服务, 首先 1 BINGING是能提供的 2 SessionMode 必须适应 3 PerSession必须,如果是PerCall则不适合。 4 不能有事务,还有就是必须有数据信道(security和reliableSession两者有一个配置了即可)

15 不要在数据契约中使用泛型。那样命名将会非常奇怪. 如果在操作契约上也没什么问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息