.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 }