服务代理的关闭与并发会话的限制
这几天将WCF的绑定由BasicHttpBinding换成了wsHttpBinding,随后问题也伴随着wsHttpBinding的绑定而来。
时而客户端得到异常:请求通道在等待 00:00:59.9840000以后答复超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能是更长超时的一部分。服务重启之后恢复正常。
在Artech博客中看到一篇相关文章:http://www.cnblogs.com/artech/archive/2009/07/04/1516908.html
整理如下:
1.信道分两种
- 会话信道(Sessionful Channel):会话信道确保客户端和服务端之间传输的消息能够相互关联,但是信道的错误(Fault)会影响后续的消息交换;
- 数据报信道(Datagram Channel):即使在同一个数据报信道中,每次消息的交换都是相互独立,信道的错误也不会影响后续的消息交换
2.信道创建
对于绝大部分绑定类型(BasicHttpBinding除外),在默认的情况下创建的都是会话信道。对于WCF客户端来说,如果进行基于会话信道的服务调用,有一些问题需要引起足够的重视(基于会话信道服务调用须要注意的第一个问题和WCF流量限制有关),如果使用不当,不但影响客户端本身的服务调用,还会对服务处理请求的吞吐量造成很大的影响。
以下为客户端调用服务的代码:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 try 6 { 7 for (int i = 0; i < 10000; i++)//循环10000次调用服务 8 { 9 SR.TestClient c = new SR.TestClient(); 10 string res = c.Login("张三", "123", "", ""); 11 Console.WriteLine("【" + i + "】"); 12 } 13 } 14 catch (Exception ex) 15 { 16 Console.WriteLine(ex.Message); 17 } 18 Console.ReadLine(); 19 } 20 }
执行结果:
出现这种情况的原因是因为在客户端调用服务后没有关闭服务代理。连接数量超出WCF对并发会话数量的控制。
WsHttpBinding在默认的情况下安全模式(SecurityMode)为基于消息的安全,所以创建出来的信道自动被赋予了会话的特性。
之前BasicHttpBinding绑定模式没有出现此问题是因为BasicHttpBinding不是会话模式
客户端调用改用如下模式即可
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 try 6 { 7 for (int i = 0; i < 10000; i++) 8 { 9 SR.TestClient c = new SR.TestClient(); 10 string res = c.Login("张三", "123", "", ""); 11 Console.WriteLine("【" + i + "】"); 12 c.Close(); 19 } 20 } 21 catch (Exception ex) 22 { 23 Console.WriteLine(ex.Message); 24 } 25 Console.ReadLine(); 26 } 27 }
以上写法虽然可以解决此问题,但是还不够完善,如果服务调用异常,将直接跳过c.Close().可更改如下
1 class Program 2 { 3 4 static void Main(string[] args) 5 { 6 WB.InSideContract_WebSiteClient wc = new WB.InSideContract_WebSiteClient(); 7 try 8 { 9 10 11 SR.TestClient c = new SR.TestClient(); 12 string res = c.Login("张三", "123", "", ""); 13 14 c.Close(); 15 16 } 17 catch (Exception ex) 18 { 19 Console.WriteLine(ex.Message); 20 Console.WriteLine(ex.InnerException.Message); 21 wc.Abort(); 22 } 23 Console.ReadLine(); 24 } 25 }