如何:在可靠会话内交换消息How to: Exchange Messages Within a Reliable Session

本主题概述了使用系统提供的绑定之一来启用可靠会话所需的步骤。这些绑定支持可靠会话,但默认情况下不支持。This topic outlines the steps required to enable a reliable session using one of the system-provided bindings that support such a session, but not by default. 可使用代码以强制方式或在配置文件中以声明方式启用可靠会话。You enable a reliable session imperatively using code or declaratively in your configuration file. 此过程使用客户端和服务配置文件来启用可靠会话,并规定消息按发送顺序到达的顺序。This procedure uses the client and service configuration files to enable the reliable session and to stipulate that the messages arrive in the same order in which they were sent.

此过程的关键部分是终结点配置元素包含一个 bindingConfiguration 属性,该属性引用名为 Binding1的绑定配置。The key part of this procedure is that the endpoint configuration element contain a bindingConfiguration attribute that references a binding configuration named Binding1. <绑定 > 配置元素通过将 <reliableSession > 元素的 enabled 属性设置为 true来引用此名称以启用可靠会话。The <binding> configuration element references this name to enable reliable sessions by setting the enabled attribute of the <reliableSession> element to true. 通过将 ordered 属性设置为 true,可为可靠会话指定有序传送保证。You specify the ordered delivery assurances for the reliable session by setting the ordered attribute to true.

有关此示例的源副本,请参阅WS 可靠会话For the source copy of this example, see WS Reliable Session.

使用 WSHttpBinding 配置服务以使用可靠会话Configure the service with a WSHttpBinding to use a reliable session

  1. 为该类型的服务定义服务协定。Define a service contract for the type of service.

    [ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);
        [OperationContract]
        double Subtract(double n1, double n2);
        [OperationContract]
        double Multiply(double n1, double n2);
        [OperationContract]
        double Divide(double n1, double n2);
    }
    
  2. 在服务类中实现该服务协定。Implement the service contract in a service class. 请注意,在服务的实现内未指定地址或绑定信息。Note that the address or binding information isn't specified inside the implementation of the service. 无需编写代码即可从配置文件中检索地址或绑定信息。You aren't required to write code to retrieve the address or binding information from the configuration file.

    public class CalculatorService : ICalculator
    {
        public double Add(double n1, double n2)
        {
            return n1 + n2;
        }
        public double Subtract(double n1, double n2)
        {
            return n1 - n2;
        }
        public double Multiply(double n1, double n2)
        {
            return n1 * n2;
        }
        public double Divide(double n1, double n2)
        {
            return n1 / n2;
        }
    } 
    
  3. 创建一个web.config文件,用于配置使用 WSHttpBindingCalculatorService 的终结点,并启用可靠会话并按顺序传递所需的消息。Create a Web.config file to configure an endpoint for the CalculatorService that uses the WSHttpBinding with reliable session enabled and ordered delivery of messages required.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
    
        <services>
          <service name="Microsoft.ServiceModel.Samples.CalculatorService">
    
            <!-- 
                 This endpoint is exposed at the base address provided by 
                 host: http://localhost/servicemodelsamples/service.svc
                 
                 Specify wsHttpBinding binding and a binding configuration 
                 to use
            -->
            <endpoint address=""
                      binding="wsHttpBinding"
                      bindingConfiguration="Binding1" 
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
    
            <!--
              The mex endpoint is explosed at 
              http://localhost/servicemodelsamples/service.svc/mex
            -->
            <endpoint address="mex"
                      binding="mexHttpBinding"
                      contract="IMetadataExchange" />
          </service>
        </services>
    
        <!-- 
             Configures WSHttpBinding for reliable sessions with ordered 
             delivery. 
        -->
        <bindings>
          <wsHttpBinding>
            <binding name="Binding1">
              <reliableSession enabled="true" ordered="true" />
            </binding>
          </wsHttpBinding>
        </bindings>
    
      </system.serviceModel>
    </configuration>
    
  4. 创建包含以下行的服务 .svc文件:Create a Service.svc file that contains the line:

    <%@ServiceHost language=c# Service="CalculatorService" %>
    
  5. 服务 .svc文件放在 INTERNET INFORMATION SERVICES (IIS)虚拟目录中。Place the Service.svc file in your Internet Information Services (IIS) virtual directory.

使用 WSHttpBinding 配置客户端以使用可靠会话Configure the client with a WSHttpBinding to use a reliable session

  1. 使用Svcutil.exe元数据实用工具()从命令行生成服务元数据中的代码:Use the ServiceModel Metadata Utility Tool (Svcutil.exe) from the command line to generate code from service metadata:

    Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
    
  2. 生成的客户端包含定义客户端实现必须满足的服务协定的 ICalculator 接口。The generated client contains the ICalculator interface that defines the service contract that the client implementation must satisfy.

    //Generated interface defining the ICalculator contract	
    [System.ServiceModel.ServiceContractAttribute(
    Namespace="http://Microsoft.ServiceModel.Samples", 
    ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")]
    public interface ICalculator
    {
        [System.ServiceModel.OperationContractAttribute(
        Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", 
        ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
        double Add(double n1, double n2);
            
        [System.ServiceModel.OperationContractAttribute(
        Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", 
        ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
        double Subtract(double n1, double n2);
            
        [System.ServiceModel.OperationContractAttribute(
        Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", 
        ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
        double Multiply(double n1, double n2);
            
        [System.ServiceModel.OperationContractAttribute(
        Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", 
        ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
        double Divide(double n1, double n2);
    }
    
  3. 生成的客户端应用程序还包含 ClientCalculator 的实现。The generated client application also contains the implementation of the ClientCalculator. 请注意,在服务的实现内部,未指定地址和绑定信息。Note that the address and binding information isn't specified anywhere inside the implementation of the service. 无需编写代码即可从配置文件中检索地址或绑定信息。You aren't required to write code to retrieve the address or binding information from the configuration file.

    // Implementation of the CalculatorClient
    public partial class CalculatorClient : 
        System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>, 
        Microsoft.ServiceModel.Samples.ICalculator
    {
        public CalculatorClient()
        {
        }
        
        public CalculatorClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
        {
        }
        
        public CalculatorClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
        {
        }
        
        public CalculatorClient(string endpointConfigurationName, 
            System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
        {
        }
        
        public CalculatorClient(System.ServiceModel.Channels.Binding binding, 
            System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
        {
        }
        
        public double Add(double n1, double n2)
        {
            return base.Channel.Add(n1, n2);
        }
        
        public double Subtract(double n1, double n2)
        {
            return base.Channel.Subtract(n1, n2);
        }
        
        public double Multiply(double n1, double n2)
        {
            return base.Channel.Multiply(n1, n2);
        }
        
        public double Divide(double n1, double n2)
        {
            return base.Channel.Divide(n1, n2);
        }
    }
    
  4. Svcutil.exe还生成使用 WSHttpBinding 类的客户端的配置。Svcutil.exe also generates the configuration for the client that uses the WSHttpBinding class. 使用 Visual Studio 时,请将配置文件命名为app.configName the configuration file App.config when using Visual Studio.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <system.serviceModel>
    
        <client>
          <!-- 
            Specify wsHttpBinding binding and a binding configuration 
            to use
          -->
          <endpoint 
              address="http://localhost/servicemodelsamples/service.svc" 
              binding="wsHttpBinding" 
              bindingConfiguration="Binding1" 
              contract="Microsoft.ServiceModel.Samples.ICalculator" />
        </client>
    
        <!-- 
          Configures WSHttpBinding for reliable sessions with ordered 
          delivery
        -->
        <bindings>
          <wsHttpBinding>
            <binding name="Binding1">
              <reliableSession enabled="true" ordered="true" />
            </binding>
          </wsHttpBinding>
        </bindings>
    
      </system.serviceModel>
    </configuration>
    
  5. 在应用程序中创建 ClientCalculator 的实例,然后调用服务操作。Create an instance of the ClientCalculator in an application and call the service operations.

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a client with given client endpoint configuration
            CalculatorClient client = new CalculatorClient();
    
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
    
            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
    
            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
    
            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
    
            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
    
  6. 编译并运行客户端。Compile and run the client.

示例Example

默认情况下,有多种系统提供的绑定支持可靠会话。Several of the system-provided bindings support reliable sessions by default. 这些方法包括:These include:

有关如何创建支持可靠会话的自定义绑定的示例,请参阅如何:使用 HTTPS 创建自定义可靠会话绑定For an example of how to create a custom binding that supports reliable sessions, see How to: Create a Custom Reliable Session Binding with HTTPS.

请参阅See also