代码改变世界

.net 客户端 WCF Binding 多次迭代

2017-07-27 19:32  残月星辰  阅读(359)  评论(0编辑  收藏  举报

因开发组态软件 C/S 版本, 使用WCF作为通信方式和服务,在开发和应用阶段执行多次的迭代,开发时是纯理论教程,采用的都是教科书的方式开发。而等到开发完成后,实际应用或者压力测试时 发现完全跟不上节奏~

迭代的第一版:

BasicHttpBinding  : 这种绑定适用于与符合 WS-Basic Profile 的 Web 服务(例如基于 ASP.NET Web 服务 (ASMX) 的服务)进行的通信。此绑定使用 HTTP 作为传输协议,并使用文本/XML 作为默认的消息编码。

我们开发项目中 执行快速开发原则 ,先用最常见的  BasicHttpBinding ,因是HTTP 传输协议,方便使用,且测试后实时性还可以.

例子只是提供创建  BasicHttpBinding  ,其他就百度下 ,不再列举 。

1            public static BasicHttpBinding CreatBasicHttpBinding()
2         {
3             return new BasicHttpBinding()
4             {
5             
6             };
7         }

 

迭代的第二版:

NetTcpBinding: 使用 TCP 协议,用于在局域网(Intranet)内跨机器通信。有几个特点:可靠性、事务支持和安全,优化了 WCF 到 WCF 的通信。限制是服务端和客户端都必须使用 WCF 来实现。
因开发产品属于组态软件,适用在工业控制自动化中,实时性要求高,所以在测试阶段发现 BasicHttpBinding 传输效率不高,造成数据的延迟 ,从而使用了
NetTcpBinding 双工通信 ,结果显示数据无延迟。
例子只是提供创建NetTcpBinding ,其他就百度下 ,不再列举 。
1      public static NetTcpBinding CreatNetTcpBinding()
2         {
3             var tcpBinding = new NetTcpBinding()
4             {
5 
6             };
7 
8             return tcpBinding;
9         }

 

迭代的第三版:

NetNamedPipeBinding使用命名管道进行安全、可靠、高效的单机服务通讯方式

   又是在测试阶段 客户端和服务器不再同一主机上,因是走的网络通信 还是稍微有点延迟 ,是在网络许可范围内 。但是之前开发的组态软件是单机版,数据都在内存中,显示的实时性是最高的 ,

   而更换成C/S架构的版本后(服务器和客户端属于在同一个主机上)与单机版对比 实时性效果确实差了好多,没办法 继续修改 !!!

通过 客户端来服务器地址是不是在同一个主机上来区分 :

同属一个主机的使用绑定名称:NetNamedPipeBinding

不再同一个主机的使用绑定名称:NetTcpBinding 

这样方式使用WCF通信的话 实时性最高,效果最好。

1         public static NetNamedPipeBinding CreatNetNamedPipeBinding()
2         {
3             return new NetNamedPipeBinding()
4             {
5 
6             };
7         }

 

迭代的第四版:

在实际项目测试我们开发的组态软件 ,发现 客户端查询服务器上历史数据,经常出现客户端通信管道关闭,意外退出 等的其他错误,造成无法通信问题

最后定位发现有两个问题:

1.  通信超时:因执行查询的时间间隔长就造成服务器查询慢,慢到已经超过WCF通道的默认超时时间~~~

2.数据量大:因执行查询的时间间隔长,造成返回的数据量特别大,已经超出WCF通道默认数据量~~

 解决问题:

1.修改  ReceiveTimeout 时间

1  ReceiveTimeout =  new TimeSpan(1,0,0)

2. 修改默认的 Buffered模式 ,改成 Streamed 

1  TransferMode = TransferMode.Streamed

 

迭代的终结版:

 1         public static NetTcpBinding CreatNetTcpBinding()
 2         {
 3             var tcpBinding = new NetTcpBinding()
 4             {
 5                 MaxBufferPoolSize = 2147483647,
 6                 MaxReceivedMessageSize = 2147483647,
 7                 TransferMode = TransferMode.Streamed,
 8                 ReceiveTimeout = new TimeSpan(1, 0, 0)
 9             };
10             tcpBinding.Security.Mode = SecurityMode.None;
11              tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
12             return tcpBinding;
13         }