zoukankan      html  css  js  c++  java
  • 服务代理的关闭与并发会话的限制

    这几天将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     }
  • 相关阅读:
    [代码质量] Git统计本次提交新增代码行数,建议每个评审commit新增行数小于400行
    [Web 安全] WASC 和 OWASP两个web安全方面组织机构介绍
    [web 前端] Npm package.json与package-lock.json文件的作用
    Mac IDEA 插件 lombok
    IDEA 导入新的项目步骤
    IDEA for Mac 快捷键
    Flink --- hello world
    LogisticRegression回归算法 Sklearn 参数详解
    keep going
    在 macOS 上快速新建 txt 文本文件
  • 原文地址:https://www.cnblogs.com/yf2011/p/4466403.html
Copyright © 2011-2022 走看看