基于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)开启的情况下,创建的信道才具有会话的特性,解决办法
6:
7:
8:
9:
3 WCF对服务的并发会话的限制给WCF客户端提出了一个要求,那就是在服务代理不再使用的情况下,应该及时将其关闭。基于服务代理对象的会话会随着服务代理的关闭而关闭。服务端在处理客户端请求的时候,如果当前并发的会话数量超过了所允许的范围,后续的请求将会被放入等待队列,以等待现有会话的结束。对于客户端来说,服务调用在允许的超时时限(默认1分钟)内还未接收到回复,则会抛出一个TimeoutException异常
4 而实际上,服务代理的关闭与否对于数据报信道来讲,没有任何意义
5 建了OrderCollection对象,并添加了10个Order对象,如果该对象被序列化,最终被序列化对象数量是多少呢?应该这样来算,OrderCollection对象本身算一个,每一个Order对象自身也算一个,Order对象具有4个属性,设置序列化的数量,
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 参考配置:
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="1000"
maxReceivedMessageSize="2147483647">
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
11
一般WCF默认很多绑定是使用安全的,一般不是Transport(TcpBinding)就是Message(WSHttpBinding)安全模式。 而且会对客户端启用身份验证。
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 不要在数据契约中使用泛型。那样命名将会非常奇怪. 如果在操作契约上也没什么问题。