精华内容
下载资源
问答
  • wcf实例模式
    2019-01-08 01:09:31

    实例上下文模式

    InstanceContextMode 控制在响应客户端调用时,如何分配服务实例。InstanceContextMode 可以设置为以下值:

    •Single – 为所有客户端调用分配一个服务实例。

    •PerCall – 为每个客户端调用分配一个服务实例。

    •PerSession – 为每个客户端会话分配一个服务实例。

    InstanceContextMode 的默认设置为 PerSession

    并发模式
    ConcurrencyMode 控制一次允许多少个线程进入服务。ConcurrencyMode 可以设置为以下值之一:

    •Single – 一次可以有一个线程进入服务。

    •Reentrant – 一次可以有一个线程进入服务,但允许回调。

    •Multiple – 一次可以有多个线程进入服务。

    ConcurrencyMode 的默认设置为 Single。

     

    实例上下文模式、并发模式和性能

    InstanceContextMode 和 ConcurrencyMode 设置可以相互影响,因此了解它们如何影响性能时,必须同时查看这两个设置。例如,将 InstanceContextMode 设置为 PerCall 时,会忽略 ConcurrencyMode 设置。这是因为,每个客户端调用都将路由到新的服务实例,因此一次只会有一个线程在服务实例中运行。将 InstanceContextMode 设置为 Single 时,仅创建一个服务实例,因此 ConcurrencyMode 会影响应用程序的吞吐量。

    将 InstanceContextMode 设置为 Single 的原因很多,其中包括:

    1. 创建服务实例需要大量的处理工作。当多个客户端访问服务时,仅允许创建一个服务实例可以降低所需处理量。
    2. 一个服务实例可以创建多个对象。将 ConcurrencyMode 设置为 Single 可以降低垃圾回收成本,因为不必为每个调用创建和销毁服务创建的对象。
    3. 通过将 ConcurrencyMode 设置为 Single,可以在多个客户端之间共享服务实例。

    如果 ConcurrencyMode 和 InstanceContextMode 均设置为 Single,则一次只允许一个客户端调用通过。如果有大量客户端,这可能会导致较大的瓶颈。

    将 InstanceContextMode 设置为 Single 并将 ConcurrencyMode 设置为 Reentrant 的性能特征与将ConcurrencyMode 设置为 Single 时相同。这是因为,一次仅允许一个客户端线程进入服务。

    InstanceContextMode 设置为 PerCall 时,将为每个客户端调用创建一个新服务实例上下文(默认情况下,这表示一个新服务实例),并在客户端调用完成时销毁该实例。由于服务实例仅在进行调用时可 用,因此在调用完成时,会释放它们可能访问的所有资源。由于为每个调用分配一个新服务实例,因此会产生一些开销。但是,由于每个客户端都获取自己的服务实 例,因此不存在同步问题。当大量客户端调用同时发生时,将创建大量的服务实例。遇此情形时,务必使服务实例仅分配其正常工作所需的那些资源。

    如果 ConcurrencyMode 设置为 Multiple,则多个客户端调用可以通过,但开发人员需负责手动同步对共享数据的所有访问。这意味着,一次只有一个线程可以访问共享数据,从而导致访问共享数据的所有调用顺序排队等候。这违背了将 ConcurrencyMode 设置为 Multiple 的初衷。

    在 InstanceContextMode 设置为 PerCall 时,ConcurrencyMode 设置对吞吐量没有影响。每个客户端调用都获取自己的服务实例,因此每个服务实例只有一个调用到其中的线程。在 InstanceContextMode 设置为 PerSession 时,每个会话都获取自己的服务实例。有关 会话的更多信息,请参见使用会话(可能为英文网页)。使用 PerSession 时,必须使用支持会话的绑定。下表显示系统提供的哪些绑定支持会话。默认会话设置括在圆括号中。

     

    绑定会话(默认)
    BasicHttpBinding(无)
    WSHttpBinding无、可靠会话、(安全会话)
    WSDualHttpBinding(可靠会话)、安全会话
    WSFederationHttpBinding(无)、可靠会话、安全会话
    NetTcpBinding(传输)、可靠会话、安全会话
    NetNamedPipeBinding无、(传输)
    NetMsmqBinding(无)、传输
    NetPeerTcpBinding(无)
    MsmqIntegrationBinding(无)
    BasicHttpContextBinding(无)
    NetTcpContextBinding(传输)、可靠会话、安全会话
    WSHttpContextBinding无、可靠会话、(安全会话)
    更多相关内容
  • 1、WCF 几种服务对象实例创建模式wcf中有三种服务对象实例创建模式:PerCall、PerSession、Single.(具体在哪里设置,最后例子中有很好的阐述)2、几种模式下服务对象实例的生命周期(这里暂不考虑Mep=Message Exchange...

    1、WCF 几种服务对象实例创建模式

    wcf中有三种服务对象实例创建模式:PerCallPerSessionSingle.(具体在哪里设置,最后例子中有很好的阐述)

    2、几种模式下服务对象实例的生命周期(这里暂不考虑Mep=Message Exchange Pattern 信息交流模式 )

    PerCall模式

    这里写图片描述

    PerCall模式工作流程如下

    客户端创建代理对象(Proxy)
    客户端调用代理对象的一个契约操作,代理对象将其传递给服务宿主程序
    宿主应用程序创建一新的服务契约对象,并且执行请求操作
    在执行完请求操作后,如果要求有应答,那么服务契约会给代理对象一个应答,然后销毁自己

    示例代码展示

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace Contract
    {
        [ServiceContract(Name="CalculatorService",Namespace="http://www/gxs.com")]
        public interface ICalculator:IDisposable
        {
            [OperationContract(Name = "CalculatorAdd")]
            double Add(double x, double y);
            [OperationContract(Name = "CalculatorSubtract")]
            double Subtract(double x, double y);
        }
    }

    服务契约代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Contract;
    using System.ServiceModel;
    
    namespace Service
    {
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
        public class CalculatorPerCall:ICalculator
        {
            public CalculatorPerCall()
            {
                Console.WriteLine("Create a new instance!!!");
            }
            public double Add(double x, double y)
            {
                Console.WriteLine("Call [Add] Method");
                return x + y;
            }
            public double Subtract(double x, double y)
            {
                Console.WriteLine("Call [Subtract] Method");
                return x - y;
            }
            public void Dispose()
            {
                Console.WriteLine("The instance has been disposed!!!");
            }
        }
    }

    服务端宿主代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using Contract;
    using Service;
    using System.ServiceModel.Description;
    
    namespace Hosting
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(CalculatorPerCall)))
                {
                    host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:8089/CalculatorService");
                    //ServiceMetadataBehavior:控制服务元数据和相关信息的发布
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetEnabled = true;
                        behavior.HttpGetUrl = new Uri("http://127.0.0.1:8089/CalculatorService/metadata");
                        host.Description.Behaviors.Add(behavior);
                    }
                    host.Opened += new EventHandler(host_Opened);
                    host.Open();
                    Console.Read();
                }
            }
    
            static void host_Opened(object sender, EventArgs e)
            {
                Console.WriteLine("计算机服务已经被打开了......");
            }
        }
    }

    客户端代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace WcfLifeCycle.Client
    {
        /// <summary>
        /// wcf实例模型
        /// </summary>
        public class ClientCalculator
        {
            public static void Main(string[] args)
            {
                CalculatorServiceClient proxy1 = new CalculatorServiceClient();
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("******************************************");
                CalculatorServiceClient proxy2= new CalculatorServiceClient();
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.Read();
            }
        }
    }

    结果示例图

    服务端:
    这里写图片描述

    客户端
    这里写图片描述

    小结:Percall模式,客户端每次发出请求后,服务端都会生成一个实例响应,响应完毕后自行销毁。

    PerSession模式

    这里写图片描述

    PerSession模式工作的流程如下:

    客户端创建代理对象(Proxy)
    客户端第一次调用代理对象的一个契约操作,代理对象将其调用请求传递给服务宿主
    宿主程序创建新的服务对象,并执行请求操作,如果有必要,返回客户端应答
    客户端再次发出调用操作的请求(图中的proxy一与服务实例一对应,proxy二与服务实例二对应),宿主会先判断是否已有建立好的会话,如果存在,则不需要再创建新的服务对象,直接使用老对象即可,如果不存在则新建一个服务对象。
    在时间达到指定要求或者因一些特殊原因,会话会过期,此时服务对象销毁.或者客户端关闭,服务对象也会自动销毁。

    示例代码展示

    服务契约代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace Contract
    {
        [ServiceContract(Name="CalculatorService",Namespace="http://www/gxs.com")]
        public interface ICalculator:IDisposable
        {
            [OperationContract(Name = "CalculatorAdd")]
            double Add(double x, double y);
            [OperationContract(Name = "CalculatorSubtract")]
            double Subtract(double x, double y);
        }
    }

    服务代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Contract;
    using System.ServiceModel;
    
    namespace Service
    {
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
        public class CalculatorPerSession : ICalculator
        {
            public CalculatorPerSession()
            {
                Console.WriteLine("Create a new instance!!!");
            }
            public double Add(double x, double y)
            {
                Console.WriteLine("Call [Add] Method");
                return x + y;
            }
            public double Subtract(double x, double y)
            {
                Console.WriteLine("Call [Subtract] Method");
                return x - y;
            }
            public void Dispose()
            {
                Console.WriteLine("The instance has been disposed!!!");
            }
        }
    }

    服务端宿主代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using Contract;
    using Service;
    using System.ServiceModel.Description;
    
    namespace Hosting
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(CalculatorPerSession)))
                {
                    host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:8089/CalculatorService");
                    //ServiceMetadataBehavior:控制服务元数据和相关信息的发布
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetEnabled = true;
                        behavior.HttpGetUrl = new Uri("http://127.0.0.1:8089/CalculatorService/metadata");
                        host.Description.Behaviors.Add(behavior);
                    }
                    host.Opened += new EventHandler(host_Opened);
                    host.Open();
                    Console.Read();
                }
            }
            static void host_Opened(object sender, EventArgs e)
            {
                Console.WriteLine("计算机服务已经被打开了......");
            }
        }
    }

    客户端代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace WcfLifeCycle.Client
    {
        /// <summary>
        /// wcf实例模型
        /// </summary>
        public class ClientCalculator
        {
            public static void Main(string[] args)
            {
                CalculatorServiceClient proxy1 = new CalculatorServiceClient();
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("******************************************");
                CalculatorServiceClient proxy2= new CalculatorServiceClient();
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy2 Call [Add] method");
                proxy2.CalculatorAdd(12d, 13d);
                Console.Read();
            }
        }
    }

    结果实例图

    服务端
    这里写图片描述

    客户端
    这里写图片描述

    小结:PerSession模式,proxy与服务实例对应。不同的proxy有不同的服务实例。

    Single模式

    Single模式的工作流程如下:

    服务端启动,同时创建服务对象
    客户端通过代理调用契约操作
    第一步中创建的服务对象接受请求 ,并执行操作,进行必要的应答
    第一步创建的服务对象将一直保留
    服务关闭,第一步创建的对象销毁

    示例代码展示:

    服务契约代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    
    namespace Contract
    {
        [ServiceContract(Name="CalculatorService",Namespace="http://www/gxs.com")]
        public interface ICalculator:IDisposable
        {
            [OperationContract(Name = "CalculatorAdd")]
            double Add(double x, double y);
            [OperationContract(Name = "CalculatorSubtract")]
            double Subtract(double x, double y);
        }
    }

    服务代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Contract;
    using System.ServiceModel;
    
    namespace Service
    {
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
        public class CalculatorPerSingle : ICalculator
        {
            public CalculatorPerSingle()
            {
                Console.WriteLine("Create a new instance!!!");
            }
            public double Add(double x, double y)
            {
                Console.WriteLine("Call [Add] Method");
                return x + y;
            }
            public double Subtract(double x, double y)
            {
                Console.WriteLine("Call [Subtract] Method");
                return x - y;
            }
            public void Dispose()
            {
                Console.WriteLine("The instance has been disposed!!!");
            }
        }
    }

    服务端宿主代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using Contract;
    using Service;
    using System.ServiceModel.Description;
    
    namespace Hosting
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(CalculatorPerSingle), new Uri("http://127.0.0.1:8089")))
                {
                    host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorServiceOne");
                    host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorServiceTwo");
                    //ServiceMetadataBehavior:控制服务元数据和相关信息的发布
                    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                    {
                        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                        behavior.HttpGetEnabled = true;
                        behavior.HttpGetUrl = new Uri("http://127.0.0.1:8089/CalculatorService/metadata");
                        host.Description.Behaviors.Add(behavior);
                    }
                    host.Opened += new EventHandler(host_Opened);
                    host.Open();
                    Console.Read();
                }
            }
            static void host_Opened(object sender, EventArgs e)
            {
                Console.WriteLine("计算机服务已经被打开了......");
            }
        }
    }

    客户端一代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace WcfLifeCycle.Client
    {
        /// <summary>
        /// wcf实例模型
        /// </summary>
        public class ClientOneCalculator
        {
            public static void Main(string[] args)
            {
                CalculatorServiceClient proxy1 = new CalculatorServiceClient("WSHttpBinding_CalculatorService");
                Console.WriteLine("I am EndPointOne");
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                proxy1.Close();
                Console.Read();
            }
        }
    }

    客户端一配置文件app.config

    <?xml version="1.0"?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="WSHttpBinding_CalculatorService" closeTimeout="00:01:00"
                        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                        allowCookies="false">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                            enabled="false" />
                        <security mode="Message">
                            <transport clientCredentialType="Windows" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                algorithmSuite="Default" />
                        </security>
                    </binding>
                    <binding name="WSHttpBinding_CalculatorService1" closeTimeout="00:01:00"
                        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                        allowCookies="false">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                            enabled="false" />
                        <security mode="Message">
                            <transport clientCredentialType="Windows" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                algorithmSuite="Default" />
                        </security>
                    </binding>
                </wsHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://127.0.0.1:8089/CalculatorServiceOne"
                    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_CalculatorService"
                    contract="Client.CalculatorService" name="WSHttpBinding_CalculatorService">
                    <identity>
                        <userPrincipalName value="guxiaoshi-PC\guxiaoshi" />
                    </identity>
                </endpoint>
                <endpoint address="http://127.0.0.1:8089/CalculatorServiceTwo"
                    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_CalculatorService1"
                    contract="Client.CalculatorService" name="WSHttpBinding_CalculatorService1">
                    <identity>
                        <userPrincipalName value="guxiaoshi-PC\guxiaoshi" />
                    </identity>
                </endpoint>
            </client>
        </system.serviceModel>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

    客户端二代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ClientTwo.Client;
    
    namespace ClientTwo
    {
        class ClientTwoCalculator
        {
            static void Main(string[] args)
            {
                CalculatorServiceClient proxy1 = new CalculatorServiceClient("WSHttpBinding_CalculatorService1");
                Console.WriteLine("I am EndPointTwo");
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                Console.WriteLine("proxy1 Call [Add] method");
                proxy1.CalculatorAdd(12d, 13d);
                proxy1.Close();
                Console.Read();
            }
        }
    }

    客户端二配置文件app.config

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="WSHttpBinding_CalculatorService" closeTimeout="00:01:00"
                        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                        allowCookies="false">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                            enabled="false" />
                        <security mode="Message">
                            <transport clientCredentialType="Windows" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                algorithmSuite="Default" />
                        </security>
                    </binding>
                    <binding name="WSHttpBinding_CalculatorService1" closeTimeout="00:01:00"
                        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                        allowCookies="false">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                            enabled="false" />
                        <security mode="Message">
                            <transport clientCredentialType="Windows" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                algorithmSuite="Default" />
                        </security>
                    </binding>
                </wsHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://127.0.0.1:8089/CalculatorServiceOne"
                    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_CalculatorService"
                    contract="Client.CalculatorService" name="WSHttpBinding_CalculatorService">
                    <identity>
                        <userPrincipalName value="guxiaoshi-PC\guxiaoshi" />
                    </identity>
                </endpoint>
                <endpoint address="http://127.0.0.1:8089/CalculatorServiceTwo"
                    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_CalculatorService1"
                    contract="Client.CalculatorService" name="WSHttpBinding_CalculatorService1">
                    <identity>
                        <userPrincipalName value="guxiaoshi-PC\guxiaoshi" />
                    </identity>
                </endpoint>
            </client>
        </system.serviceModel>
    </configuration>

    结果实例图

    服务端
    这里写图片描述

    客户端一

    这里写图片描述

    客户端二

    这里写图片描述

    小结:服务端自始至终只有一个实例与客户端进行消息的交换。

    总结:上文是对服务对象实例生命周期的介绍.Percall:新的请求产生新的服务对象与之交换信息,服务对象自行销毁;PerSession:相同的客户端由同一个服务对象与之交换信息(这里的客户端指proxy);Single:服务端只有一个服务实例,服务打开时服务实例就会被创建。

    展开全文
  • wcf实例化-单调服务模式,言简意赅,很容易理解。就是现在积分没发控制,不然1分即可。很简单的代码
  • 基于C#技术 wcf的应用实例 分控制台宿主和Windows服务宿主两种模式
  • WCF简单实例详解

    2021-12-20 13:24:28
    xfserver:是一个类库项目,定义服务契约(Service Contract),提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,该项目引用System.ServiceMode程序集; WCF采用基于契约...

    • xfserver:是一个类库项目,定义服务契约(Service Contract),提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,该项目引用System.ServiceMode程序集;

      WCF采用基于契约的交互方式实现了服务的自治,以及客户端和服务端之间的松耦合。WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约,这里着重于服务契约。从功能上讲,服务契约抽象了服务提供的所有操作;而站在消息交换的角度来看,服务契约则定义了基于服务调用的消息交换过程中,请求消息和回复消息的结构,以及采用的消息交换模式。通过接口的形式定义服务契约:

    •  [ServiceContract]
          public interface IFirstService //定义接口
          {
              [OperationContract]
             String GetData(String name); //不需要public
          }

    • 当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务FirstService定义在本项目中,实现了服务契约接口IFirstService,实现了所有的服务操作。FirstService定义如下:

    • public class FirstService : IFirstService//实现接口
          {
           public   string GetData(String name)//需要public
              {
                  return String.Format("Hello {0},Welcome To WCF!", name);
              }
          }

    • Host一个控制台(Console)应用,实现对定义在xfserver项目中的服务的寄宿,该项目须要引用xfserver项目和System.ServiceMode程序集,由于WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。在我们的服务应用中,可以采用了两种服务寄宿方式:通过自我寄宿(Self-Hosting)的方式创建一个控制台应用作为服务的宿主(寄宿进程为Host.exe);通过IIS寄宿方式将服务寄宿于IIS中(暂不介绍)。

      服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息。

    • 地址(Address):地址决定了服务的位置,解决了服务寻址的问题;
    • 地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定。URI由通讯协议和位置路径两部分组成,如示例一中的:
      http://localhost:8000/
      表明通讯协议为http,位置是localhost(本机)的8000端口。
          注意上述提到的消息是指一个独立的数据单元,一般由消息正文和消息头组成,而服务端与客户端的交互都是通过消息来进行的。
          WCF中支持的传输协议包括HTTP、TCP、Peer network(对等网)、IPC(基于命名管道的内部进程通信)以及MSMQ(微软消息队列),每个协议对应一个地址类型:
          HTTP地址
              即使用HTTP协议进行传输(包括https安全传输协议)。其地址形式为
              http://localhost:8000/
              如果地址中为制定端口号,则默认端口为80

          TCP地址
              使用TCP协议进行传输,其形式为:
              net.tcp://localhost:8000/

          IPC地址
              使用net.pipe进行传输,其形式为:
              net.pipe://localhost/

          MSMQ地址
              使用Microsoft Message Queue机制进行传输,其形式为:
              net.msmq://localhost/

          对等网地址
              使用net.p2p进行传输,其形式为:
              net.p2p://localhost/

    • 绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等;
    • 绑定定义终结点与外界进行通讯的方式,它由一组称为绑定元素的要素构造而成,绑定最起码应该定义传输协议(如http、TCP等)和所使用的编码方式(如文本或二进制等)
      绑定元素
          绑定元素表示绑定的特定部分,如传输协议、编码、基础结构级协议(如 WS-ReliableMessaging)的实现以及通信堆栈的其他任何要素。
      预定义绑定
          即WCF基库中提供的绑定。 这些绑定是针对特定方案进行优化的绑定元素的集合。 例如,WSHttpBinding 是为了与实现各种 WS* 规范的服务进行互操作而专门设计的。 通过仅提供那些可以正确应用于特定方案的选项,这些预定义的绑定可以节省时间。 如果预定义的绑定不能满足您的要求,则可以创建您自己的自定义绑定。示例一中我们使用了basicHttpBinding预定义绑定。
      下面列表包含了当前WCF基库中预定义的所有绑定

      绑定配置元素说明传输协议编码格式
      BasicHttpBinding<basicHttpBinding>一个绑定,适用于与符合 WS-Basic Profile 的 Web 服务(例如基于 ASP.NET Web 服务 (ASMX) 的服务)进行的通信。 此绑定使用 HTTP 作为传输协议,并使用文本/XML 作为默认的消息编码。HTTP/HTTPSText,MTOM
      WSHttpBinding<wsHttpBinding>一个安全且可互操作的绑定,适合于非双工服务约定。HTTP/HTTPSText,MTOM
      WS2007HttpBinding<ws2007HttpBinding>一个安全且可互操作的绑定,可为 Security, ReliableSession 的正确版本和 TransactionFlow 绑定元素提供支持。HTTP/HTTPSText,MTOM
      WSDualHttpBinding<wsDualHttpBinding>一个安全且可互操作的绑定,适用于双工服务协定或通过 SOAP 媒介进行的通信。HTTPText,MTOM
      WSFederationHttpBinding<wsFederationHttpBinding>一个安全且可互操作的绑定,支持 WS 联合协议并使联合中的组织可以高效地对用户进行身份验证和授权。HTTP/HTTPSText,MTOM
      WS2007FederationHttpBinding<ws2007FederationHttpBinding>一个安全且可互操作的绑定,它派生自 WS2007HttpBinding 并支持联合安全性。HTTP/HTTPSText,MTOM
      NetTcpBinding<netTcpBinding>一个安全且经过优化的绑定,适用于 WCF 应用程序之间跨计算机的通信。TCPBinary
      NetNamedPipeBinding<netNamedPipeBinding>一个安全、可靠且经过优化的绑定,适用于 WCF 应用程序之间计算机上的通信。IPCBinary
      NetMsmqBinding<netMsmqBinding>一个排队绑定,适用于 WCF 应用程序之间跨计算机的通信。MSMQBinary
      NetPeerTcpBinding<netPeerTcpBinding>一个支持多计算机安全通信的绑定。P2PBinary
      MsmqIntegrationBinding<msmqIntegrationBinding>一个绑定,适用于 WCF 应用程序和现有消息队列(也称为 MSMQ)应用程序之间跨计算机的通信。MSMQBinary

      显然绑定与地址是对应的:比如NetTcpBinding绑定只能使用TCP地址。而上表中所有WS开始的绑定都支持TEXT的SOAP消息编码,这表明选择这些绑定的服务,可以由其他技术和平台使用,如Java等。而其他采用二进制SOAP编码的绑定则只支持WCF到WCF的交互。

    • 契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。
    • 一般通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置。
    • <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
          <system.serviceModel>
              <services>
                  <service name="XfServer.FirstService" behaviorConfiguration="behaviorConfiguration">
                      <host>
                          <baseAddresses>
                              <add baseAddress="http://localhost:8000/"/>
                          </baseAddresses>
                      </host>
                      <endpoint address="" binding="basicHttpBinding" contract="XfServer.IFirstService"></endpoint>
                  </service>
              </services>
              <behaviors>
                  <serviceBehaviors>
                      <behavior name="behaviorConfiguration">
                          <serviceMetadata httpGetEnabled="true"/>
                      </behavior>
                  </serviceBehaviors>
              </behaviors>
          </system.serviceModel>
      </configuration>
    • 对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。在这种情况下,可以直接使用VS提供的配置工具。你可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器。
    • Client一个控制台应用模拟服务的客户端,该项目引用System.ServiceMode程序集。客户端通过另一个控制台应用模拟(进程为Client.exe);服务被成功寄宿后,服务端便开始了服务调用请求的监听工作。此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据创建客户端程序进行服务的消费。借助这些元数据通过代码生成工具(SvcUtil.exe)自动生成用于服务调用的服务代理相关的代码和相应的配置。

    展开全文
  • Wcf双工实例

    2017-06-16 15:15:47
    实现客户端订阅,WCF服务端回调应答,双工通信。net.tcp模式
  • 转自 ... 参考另一个:http://www.codeproject.com/Articles/188749/WCF-Sessions-Brief-Introduction 1、WCF 几种服务对象实例创建模式 wcf中有三种服务对象实例创建模式:PerCall、Pe...

    转自 http://www.cnblogs.com/smallstone/archive/2011/12/07/2277194.html

    参考另一个:http://www.codeproject.com/Articles/188749/WCF-Sessions-Brief-Introduction

    1、WCF 几种服务对象实例创建模式

    wcf中有三种服务对象实例创建模式:PerCall、PerSession、Single.(具体在哪里设置,最后例子中有很好的阐述)

    2、几种模式下服务对象实例的生命周期(这里暂不考虑Mep)

     PerCall模式

      PerCall模式工作流程如下

    •    客户端创建代理对象(Proxy)
    •    客户端调用代理对象的一个契约操作,代理对象将其传递给服务宿主程序
    •    宿主应用程序创建一新的服务契约对象,并且执行请求操作
    •    在执行完请求操作后,如果要求有应答,那么服务契约会给代理对象一个应答,然后销毁自己

      示例代码展示

      服务契约代码如下:

     

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;

    namespace Contract
    {
    [ServiceContract(Name="CalculatorService",Namespace="http://www/gxs.com")]
    public interface ICalculator:IDisposable
    {
    [OperationContract(Name = "CalculatorAdd")]
    double Add(double x, double y);
    [OperationContract(Name = "CalculatorSubtract")]
    double Subtract(double x, double y);
    }
    }
    复制代码

    服务代码如下:

     

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Contract;
    using System.ServiceModel;

    namespace Service
    {
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class CalculatorPerCall:ICalculator
    {
    public CalculatorPerCall()
    {
    Console.WriteLine("Create a new instance!!!");
    }
    public double Add(double x, double y)
    {
    Console.WriteLine("Call [Add] Method");
    return x + y;
    }
    public double Subtract(double x, double y)
    {
    Console.WriteLine("Call [Subtract] Method");
    return x - y;
    }
    public void Dispose()
    {
    Console.WriteLine("The instance has been disposed!!!");
    }
    }
    }
    复制代码

     

    服务端宿主代码如下:

     

     

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using Contract;
    using Service;
    using System.ServiceModel.Description;

    namespace Hosting
    {
    class Program
    {
    static void Main(string[] args)
    {
    using (ServiceHost host = new ServiceHost(typeof(CalculatorPerCall)))
    {
    host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:8089/CalculatorService");
    //ServiceMetadataBehavior:控制服务元数据和相关信息的发布
    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
    {
    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
    behavior.HttpGetEnabled = true;
    behavior.HttpGetUrl = new Uri("http://127.0.0.1:8089/CalculatorService/metadata");
    host.Description.Behaviors.Add(behavior);
    }
    host.Opened += new EventHandler(host_Opened);
    host.Open();
    Console.Read();
    }
    }

    static void host_Opened(object sender, EventArgs e)
    {
    Console.WriteLine("计算机服务已经被打开了......");
    }
    }
    }
    复制代码



    客户端代码如下:

     

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace WcfLifeCycle.Client
    {
    /// <summary>
    /// wcf实例模型
    /// </summary>
    public class ClientCalculator
    {
    public static void Main(string[] args)
    {
    CalculatorServiceClient proxy1 = new CalculatorServiceClient();
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("******************************************");
    CalculatorServiceClient proxy2= new CalculatorServiceClient();
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.Read();
    }
    }
    }
    复制代码

     结果示例图

     服务端:

    客户端

    小结:Percall模式,客户端每次发出请求后,服务端都会生成一个实例响应,响应完毕后自行销毁。

     PerSession模式

     

    PerSession模式工作的流程如下:

    • 客户端创建代理对象(Proxy) 
    • 客户端第一次调用代理对象的一个契约操作,代理对象将其调用请求传递给服务宿主
    • 宿主程序创建新的服务对象,并执行请求操作,如果有必要,返回客户端应答
    • 客户端再次发出调用操作的请求(图中的proxy一与服务实例一对应,proxy二与服务实例二对应),宿主会先判断是否已有建立好的会话,如果存在,则不需要再创建新的服务对象,直接使用老对象即可,如果不存在则新建一个服务对象。
    • 在时间达到指定要求或者因一些特殊原因,会话会过期,此时服务对象销毁.或者客户端关闭,服务对象也会自动销毁。

    示例代码展示

      服务契约代码如下:

     

    View Code

    服务代码如下:

     

    View Code

     

     

    服务端宿主代码

     

    View Code

     


    客户端代码如下:

     

    View Code
    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace WcfLifeCycle.Client
    {
    /// <summary>
    /// wcf实例模型
    /// </summary>
    public class ClientCalculator
    {
    public static void Main(string[] args)
    {
    CalculatorServiceClient proxy1 = new CalculatorServiceClient();
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy1 Call [Add] method");
    proxy1.CalculatorAdd(12d, 13d);
    Console.WriteLine("******************************************");
    CalculatorServiceClient proxy2= new CalculatorServiceClient();
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.WriteLine("proxy2 Call [Add] method");
    proxy2.CalculatorAdd(12d, 13d);
    Console.Read();
    }
    }
    }
    复制代码


    结果实例图

    服务端

     

     

    客户端

     

    小结:PerSession模式,proxy与服务实例对应。不同的proxy有不同的服务实例。

    Single模式

     

    Single模式的工作流程如下:

    • 服务端启动,同时创建服务对象
    • 客户端通过代理调用契约操作
    • 第一步中创建的服务对象接受请求 ,并执行操作,进行必要的应答
    • 第一步创建的服务对象将一直保留
    • 服务关闭,第一步创建的对象销毁

    示例代码展示:

    服务契约代码

     

    View Code

     
    服务代码

    View Code

    服务端宿主代码

    View Code

     

    客户端一代码

    View Code

    客户端一配置文件app.config

    View Code

    客户端二代码

    View Code

    客户端二配置文件app.config

    View Code

    结果实例图

    服务端

    客户端一

    客户端二

    小结:服务端自始至终只有一个实例与客户端进行消息的交换。

    总 结:上文是对服务对象实例生命周期的介绍.Percall:新的请求产生新的服务对象与之交换信息,服务对象自行销毁;PerSession:相同的客户 端由同一个服务对象与之交换信息(这里的客户端指proxy);Single:服务端只有一个服务实例,服务打开时服务实例就会被创建。

    转载于:https://www.cnblogs.com/webglcn/archive/2012/05/02/2479873.html

    展开全文
  • 手把手wcf简单实例

    2021-12-20 10:59:22
    WCF是微软为构建面向服务的应用程序所提供的统一编程模型。 下面通过一个简单的服务示例来认识WCF 1.新建项目,名称 XfServer,解决方案名称 XfStudy,模板选择类库,选择.NET Framework版本 2.修改Class1.cs文件...
  • 实例是一个关于配置WCF、编写WCF服务到调用的,里面会教你手动生成对应的WSDL。此实例基本借鉴 Robin关于WCF第七节中的思想。
  • 为了让读者对REST在WCF中的应用有一个大致的了解,我们先来进行一个简单的实例演示。[源代码从这里下载]  微软在WCF3.5中就通过提供基于WebHTTP的编程模式使我们很容易地创建基于REST的服务,WCF4.0中对此进行了较...
  • InstanceContextMode为服务端实现服务契约类的实例模式,有三种类型,分别为:PerCall-每次服务操作调用创建一次, 调用完后进行销毁;PerSession-同一个会话期间创建一次,客户端代理第一次操作(IsInitiating = ...
  • 很多情况下,我们都需要控制wcf服务端对象的初始化方式,用来控制wcf实例在服务端的存活时间。 Wcf框架提供了三种创建wcf实例的方式。 WCF服务对象实例化基础 在普通的WCF请求和相应过程中,将产生下列活动: ...
  • 概述WCF陆陆续续也用过多次,但每次都是浅尝辄止,以将够解决问题为王道,这几天稍闲,特寻了些资料看,昨晚尝试使用WCF的双工模式实现了一个简单的即时通讯程序,通过服务端转发实现客户端之间的通讯。这只是个Demo...
  • WCF的通信模式

    多人点赞 2020-04-21 23:52:58
    WCF在通信过程中有三种模式:请求与答复、单向、双工通信。以下我们一一介绍。 请求与答复模式:客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后才能继续执行其他...
  • 一个傻瓜式的Windows服务宿主模式下的WCF的完整示例 全部文档包含:代码,说明文档,编译后文件 只注重于实现,不讲理论
  • WCF简单实例

    千次阅读 2019-04-11 19:38:23
    WCF是各种分布式技术的集大成者 WCF有服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。 我们采用自我寄宿(Self-...
  • WCF 提供了三种实例上下文模式:PreCall、PreSession 以及 Single。开发人员通过 ServiceBehavior.InstanceContextMode 就可以很容易地控制服务对象的实例管理模式。而当 WCF 释放服务对象时,会检查该对象是否实现...
  • WCF 双工、单向模式代码Demo
  • 1、WCF实例化,是指对用户定义的服务对象以及与其相关的实例上下文对象的生存期的控制,也就是说每一个服务类其实就是一个服务实例,客户端在调用服务端中的服务方法时,需要实例化一个服务端代理类对象,实例化就是对这...
  • WCF实例模式类型与区别 实例化模式 instanceMode percall 单调模式 [ServiceBehavior(InstanceContextMode=InstanceContext...
  • WCF实例生命周期

    2018-02-05 21:06:47
    WCF的工作原理 首先: WCF的全称是Windows Communication Foundation,Windows通信基础的意思,是Microsoft为构建面向服务的应用程序而提供的统一编程模型,它整合.NET平台下所有和分布式系统有关的技术。 其次:...
  • WCF通信模式

    2017-09-12 23:34:35
    WCF通信模式WCF在通信过程中有三种模式:请求与答复、单向、双工通信请求与答复模式客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后才能继续执行其他程序,该模式...
  • 每次调用服务是Windows通讯基础的默认实例激活模式。当一个WCF服务配置为每个调用服务,一个CLR对象是时间跨度客户调用或请求进行创建。 CLR代表公共语言运行库,并在WCF服务实例。 在每个调用服务,每一个...
  • 这是我作为一个初学WCF实例,简单的应用web service和调用互联网上的weather服务

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,138
精华内容 3,255
热门标签
关键字:

wcf实例模式