当前位置:w88优德官网网文章中心网站开发其他 → WCF学习:Instance context model(实例模型) 与 Session(会话) 的关系

WCF学习:Instance context model(实例模型) 与 Session(会话) 的关系

减小字体 增大字体 作者:admin  来源:www.cuoxin.com  发布时间:2015-12-8 0:37:46
        在WCF中对Session是默认支持的,但是和ASP.NET中的支持完全不同,说到Session,那么肯定有服务端(Service)和客户端(Client),客户端通过代理(Proxy)来访问服务端,所以Session的周期和Proxy的周期绑定。对分布式的程序而言,根据业务的要求,我们会有三种需求:
        第一:服务端不用保存客户端的状态,每次客户端的访问都是独立的;
        第二:服务端需要保持客户端的状态,每次客服端的请求会用到同一个Session; 
        第三:在多用户中共享同一个实例(其实这里类似ASP.NET中的Application,但完全不一样)。
       下面我们就针对上述的三种要求,分享一下再WCF中的实现方式. 以及各种实现方式的优势和缺点。对上述三种使用场景,WCF已经提供了良好的支持,这就是Instancing Management。具体是实现方式是:Instance context model。可以这么说,Instance Context Mode决定着不同的Session表现。WCF中有三种 Instance Context Mode,他们分别是:
        >> Per-Call:每次的客户端请求分配一个新的服务实例。 类似于Net Remoting的SingleCall模式, 在这种方式下,程序的扩展性是最强的,在事务编程与队列服务中优势更为明显。但是由于频繁地创建与销毁实例,会对性能造成一定的影响。当然网上的牛人,已经考虑到使用线程池的方式来减少频繁地创建与销毁实例(参考地址:http://www.cnblogs.com/artech/archive/2008/08/05/1260594.html)
        >> PerSession: 服务端需要保持客户端的状态,为每次客户端连接分配一个服务实例,客户端的每次调用,会使用到同一个实例,如果实例销毁,客户端的调用会抛出异常。类似于Net Remoting的客户端激活模式;这是wcf的默认支持方式. 由于每个客户端都需要维护一个会话,需要占用较多的资源来保存服务会话状态。如果存在多个独立的客户端,则创建专门的服务实例的代价太大。
        >> Singleton: 所有客户端而言,都只有一个服务实例,当服务端被host的时候,就会创建,有且仅有一个服务实例来响应客户端服务调用的请求,在多个客户端请求下,服务端只会处理一个客户端的请求,其他的排队等候处理。因此在系统的吞吐量、相应效率、系统服务性能上都存在严重的瓶颈
好处是,可以共享数据.
      特别的强调两点:
      第一:上述三种 Instance context model ,但是并不是所有的Binding都支持 Session ,对Per-Call和Singleton而言,binding影响不大。对PerSession,就必须使用特定的Binding, 才可以,否则最终指向的是PerCall,见下表:      
BindingSession modeContext modeAsync Dispose()Instance mode
BasicAllowed/NotAllowedPerCall/PerSessionYesPerCall
TCP, IPCAllowed/RequiredPerCallNoPerCall
TCP, IPCAllowed/RequiredPerSessionYesPerSession
WS (no security, no reliability)NotAllowed/AllowedPerCall/PerSessionYesPerCall
WS (with security or reliability)Allowed/RequiredPerSessionYesPerSession
WS (with security or reliability)NotAllowedPerCall/PerSessionYesPerCall
       第二:由于PerSession, 为每次客户端连接分配一个服务实例,会消耗服务器的资源,所以可以把PerSession和PerCall结合使用。在特定的条件下我们完全可以在客户端的Message中包括特定的用户****来,请求PerCall,来代替每次请求PerSession。当然这是在特定的情况下。
      下面来看具体的执行代码:
      1、建立服务契约
    [ServiceContract(Namespace = "http://www.cnblogs.com/wanqiming/")]
    public interface IInstanceContextMode
    {
        //操作契约
        [OperationContract]
        void SayHello();
    }  
      2、实现PerCall,PerSession,Single的服务类
    #region PerCall    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class WCFServicePerCall : IInstanceContextMode, IDisposable
    {
        //服务实例计数
        private int mCcount = 0;
        //构造函数
        public WCFServicePerCall()
        {
            Console.WriteLine("WCFServicePerCall Instance is Created ");
        }
        //实现接口定义的方法
        public void SayHello()
        {
            mCcount++;
            Console.WriteLine("WCFServicePerCall Instance Count is: {0} ", mCcount);
        }
        //实现接口定义的方法Dispose
        public void Dispose()
        {
            Console.WriteLine("WCFServicePerCall Instance is disposed ");
        }
    }
    #endregion      #region PerSession
    //3.服务类.会话服务
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class WCFServicePerSession : IInstanceContextMode
    {
        //服务实例计数
        private int mCcount = 0;
        //构造函数
        public WCFServicePerSession()
        {
            Console.WriteLine("WCFServicePerSession Instance is Created ");
        }
        //实现接口定义的方法
        public void SayHello()
        {
            mCcount++;
            Console.WriteLine("WCFServicePerSession Instance Count is: {0} ", mCcount);
        }
        //实现接口定义的方法Dispose
        public void Dispose()
        {
            Console.WriteLine("WCFServicePerSession Instance is disposed ");
        }
    }
    #endregion
    #region Single
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class WCFServiceSingleTon : IInstanceContextMode
    {
        //服务实例计数
        private int mCcount = 0;
        //构造函数
        public WCFServiceSingleTon()
        {
            Console.WriteLine("WCFServiceSingleTon Instance is Created ");
        }
        //实现接口定义的方法
        public void SayHello()
        {
            mCcount++;
            Console.WriteLine("WCFServiceSingleTon Instance Count is: {0} ", mCcount);
        }
        //实现接口定义的方法Dispose
        public void Dispose()
        {
            Console.WriteLine("WCFServiceSingleTon Instance is disposed ");
        }
    }
    #endregion
       第三:服务端的配置文件
      <behaviors>
        <serviceBehaviors>
          <behavior name="DefaultBehavior">
            <serviceMetadata httpGetEnabled="true" />
            <serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" maxConcurrentInstances="100" />
            <serviceDebug includeExceptionDetailInFaults="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>        <services>
          
        <service  name="Fish.ServiceImpl.WCFServicePerCall">
          <endpoint address="" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <endpoint address="" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <host>
            <baseAddresses>
              <add baseAddress="http://localhost:8080/Fish/WCFServicePerCall/>
              <add baseAddress="net.tcp://localhost:808/Fish/WCFServicePerCall"/>
            </baseAddresses>
          </host>
        </service>
        <service name="Fish.ServiceImpl.WCFServicePerSession">
          <endpoint address="" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <endpoint address="" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <host>
            <baseAddresses>
              <add baseAddress="net.tcp://localhost:808/Fish/WCFServicePerSession"/>
              <add baseAddress="http://localhost:8080/Fish/WCFServicePerSession/>
            </baseAddresses>
          </host>
        </service>
       
        <service behaviorConfiguration="DefaultBehavior" name="Fish.ServiceImpl.WCFServiceSingleTon">
          <endpoint address="" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <endpoint address="" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode"></endpoint>
          <host>
            <baseAddresses>
              <add baseAddress="net.tcp://localhost:808/Fish/WCFServiceSingleTon"/>
              <add baseAddress="http://localhost:8080/Fish/WCFServiceSingleTon/>
            </baseAddresses>
          </host>
        </service>
          
       第四:Host
     class Program
    {
        static void Main(string[] args)
        {
            try
            {
                List<ServiceHost> hosts = new List<ServiceHost>();
                hosts.Add(new ServiceHost(typeof(WCFServicePerCall)));          //PerCall
                hosts.Add(new ServiceHost(typeof(WCFServicePerSession)));       //PerSession
                hosts.Add(new ServiceHost(typeof(WCFServiceSingleTon)));        //SingleTon
                
                hosts.ForEach(host => host.Open());
                Console.WriteLine("All services are started...");
                Console.Read();
            }
            catch(Exception e)
            {
                Console.WriteLine("错误信息是:"+e.ToString());
            }
        }
    }
 
      第五:客户端执行代码
class Program
    {
        static void Main(string[] args)
        {
            PerCall();
            PerSession();            Single();            Console.WriteLine("  ");        }        #region PerCall
        private static void PerCall()
        {
            var perCall = new ChannelFactory<IInstanceContextMode>("tcpPerCall").CreateChannel();
            perCall.SayHello();
            perCall.SayHello();
            perCall.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(perCall);
            
            var tcpPerCall = new ChannelFactory<IInstanceContextMode>("tcpPerCall").CreateChannel();
            tcpPerCall.SayHello();
            tcpPerCall.SayHello();
            tcpPerCall.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(tcpPerCall);
         }
        #endregion
        #region PerSession
        private static void PerSession()
        {
            var perSession = new ChannelFactory<IInstanceContextMode>("basicHttpPerSession").CreateChannel();
            perSession.SayHello();
            perSession.SayHello();
            perSession.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(perSession);
            var tcpPerSession = new ChannelFactory<IInstanceContextMode>("tcpPerSession").CreateChannel();
            tcpPerSession.SayHello();
            tcpPerSession.SayHello();
            tcpPerSession.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(tcpPerSession);

        }
        #endregion
        #region Single
        private static void Single()
        {
            var perSession = new ChannelFactory<IInstanceContextMode>("basicHttpSingleTon").CreateChannel();
            perSession.SayHello();
            perSession.SayHello();
            perSession.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(perSession);
            var tcpPerSession = new ChannelFactory<IInstanceContextMode>("tcpSingleTon").CreateChannel();
            tcpPerSession.SayHello();
            tcpPerSession.SayHello();
            tcpPerSession.SayHello();
            ServiceBroker.DisposeService<IInstanceContextMode>(tcpPerSession);

        }
        #endregion
    }


      第六:客户端配置文件
    <client>
      <endpoint name="httpPerCall" address="http://localhost:8080/Fish/WCFServicePerCall" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
      <endpoint name="tcpPerCall" address="net.tcp://localhost:808/Fish/WCFServicePerCall" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
      <endpoint name="basicHttpPerSession" address="http://localhost:8080/Fish/WCFServicePerSession" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
      <endpoint name="tcpPerSession" address="net.tcp://localhost:808/Fish/WCFServicePerSession" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
      <endpoint name="basicHttpSingleTon" address="http://localhost:8080/Fish/WCFServiceSingleTon" binding="basicHttpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
      <endpoint name="tcpSingleTon" address="net.tcp://localhost:808/Fish/WCFServiceSingleTon" binding="netTcpBinding" contract="Fish.ServiceInterfaces.IInstanceContextMode" ></endpoint>
    </client>
      执行的结果如下:

本文引用网址:
在下列搜索引擎中搜索“WCF学习:Instance context model(实例模型) 与 Session(会话) 的关系”的相关信息:
谷歌搜索 百度搜索 360搜索 雅虎搜索 搜狗搜索 搜搜搜索 必应搜索 有道搜索
你可能还喜欢以下文章
  • 1王梦溪未经处理雅照120P完整艳...
  • 2如何做爱真人示范图片 男女ML常...
  • 3王梦溪未经处理照曝光 王梦溪口...
  • 4雨后小故事、雨后小故事01动态...
  • 5情侣酒店开房qvod 情侣做爱视频...
  • 1女性18岁身份证号大全 成年女人...
  • 24月20日免费送QQ号,5位QQ,6位...
  • 3织梦dedecms 忘记管理员后台密...
  • 417岁女孩身份证号大全 18岁女孩...
  • 5DedeCMS提示Call to a member ...
  • 1什么姿势女的最爽?最刺激的做...
  • 2兰州警花王梦溪裸照全集视频 王...
  • 3合肥艳照门事件 合肥艳照门全套...
  • 4中国女大学生的淫靡生活
  • 590后女高潮表情 美女高潮表情最...
  • 1Linux 避免IO hang方法
  • 2linux服务器在运行210天左右宕...
  • 3基于反向代理的Web缓存加速现代...
  • 4巧识硬盘“变”大的伎俩
  • 5服务器入门:菜鸟必须了解的五...
  • 赞助商广告

    图片文章导读