zoukankan      html  css  js  c++  java
  • 构建WCF的消息代理

             有时在项目中,由于部署的原因。我们需要对原来的WCF Service做一个代理,实现消息完全转发。WCF中我们可以这样实现,假设有这样的Service

       1:      [ServiceContract]
       2:      public interface IMath
       3:      {
       4:          [OperationContract]
       5:          double Add(double A, double B);
       6:      }

    实现:
       1:      public class Math : IMath
       2:      {
       3:          public double Add(double A, double B)
       4:          {
       5:              return A + B;
       6:          }
       7:      }

    然后我们Host一个service, address是 http://localhost:24258/Math.svc ,然后我们测试它:

       1:          [TestMethod]
       2:          public void TestMessageForSVCHost()
       3:          {
       4:              using (var myChannelFactory = new ChannelFactory<IMath>(new BasicHttpBinding(), "http://localhost:24258/Math.svc"))
       5:              {
       6:                  // Create a channel.
       7:                  IMath wcfClient1 = myChannelFactory.CreateChannel();
       8:                  var s = wcfClient1.Add(1, 234);
       9:                  Console.WriteLine(s.ToString());
      10:                  ((IClientChannel)wcfClient1).Close();
      11:   
      12:                  myChannelFactory.Close();
      13:   
      14:                  Assert.AreEqual(235, s);
      15:              }
      16:          }

    现在我们来增加一个Proxy Interface:

        using System.ServiceModel;
        using System.ServiceModel.Channels;
     
        /// <summary>
        /// The i pass through service.
        /// </summary>
        [ServiceContract]
        public interface IPassThroughService
        {
            #region Public Methods
     
            /// <summary>
            /// The process message.
            /// </summary>
            /// <param name="message">
            /// The message.
            /// </param>
            /// <returns>a meeage
            /// </returns>
            [OperationContract(Action = "*", ReplyAction = "*")]
            Message ProcessMessage(Message message);
     
            #endregion
        }

    实现:

        using System;
        using System.ServiceModel;
        using System.ServiceModel.Channels;
     
        /// <summary>
        /// PassThroughService class
        /// </summary>
        public class PassThroughService : IPassThroughService
        {
            /// <summary>
            /// Processes the message.
            /// </summary>
            /// <param name="requestMessage">The request message.</param>
            /// <returns>response Message</returns>
            public Message ProcessMessage(Message requestMessage)
            {
                using (var factory = new ChannelFactory<IPassThroughService>("testserver"))
                {
                    IPassThroughService proxy = factory.CreateChannel();
     
                    using (proxy as IDisposable)
                    {
                        var responseMessag = proxy.ProcessMessage(requestMessage);
                        return responseMessag;
                    }
                }
            }
        }

    然后在代理WCF项目,配制节是这样的:

       1:    <system.serviceModel>
       2:      <behaviors>
       3:        <serviceBehaviors>
       4:          <behavior>
       5:            <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
       6:            <serviceMetadata httpGetEnabled="true"/>
       7:            <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
       8:            <serviceDebug includeExceptionDetailInFaults="true"/>
       9:          </behavior>
      10:        </serviceBehaviors>
      11:      </behaviors>
      12:      <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      13:      <client>
      14:        <!-- Note: contract use another service contact -->
      15:        <endpoint name="testserver" address="http://localhost:24258/Math.svc" binding="basicHttpBinding"
      16:                   contract="ProxyWCFService.IPassThroughService"/>
      17:      </client>
      18:    </system.serviceModel>

    注意第15行代码,我们指定了是我们目标Service address,而Contact则是 IPassThroughService, ProxyWCFService是Namespace.

    然后我们Host这个代理Service, 到这个address  http://localhost:30096/PassThroughService.svc ,此时你查询的WDSL是这样的:

       1:  <?xml version="1.0" encoding="utf-8"?>
       2:  <wsdl:definitions name="PassThroughService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">
       3:    <wsdl:types/>
       4:    <wsdl:portType name="IPassThroughService"/>
       5:    <wsdl:binding name="BasicHttpBinding_IPassThroughService" type="tns:IPassThroughService">
       6:      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
       7:    </wsdl:binding>
       8:    <wsdl:service name="PassThroughService">
       9:      <wsdl:port name="BasicHttpBinding_IPassThroughService" binding="tns:BasicHttpBinding_IPassThroughService">
      10:        <soap:address location="http://localhost:30096/PassThroughService.svc"/>
      11:      </wsdl:port>
      12:    </wsdl:service>
      13:  </wsdl:definitions>


    接着我们来看UnitTest:

       1:          [TestMethod]
       2:          public void TestCilentWithProxyMessage()
       3:          {
       4:              using (var myChannelFactory = new ChannelFactory<IMath>(new BasicHttpBinding(), "http://localhost:30096/PassThroughService.svc"))
       5:              {
       6:                  // Create a channel.
       7:                  IMath wcfClient1 = myChannelFactory.CreateChannel();
       8:                  var s = wcfClient1.Add(1, 234);
       9:                  Console.WriteLine(s.ToString());
      10:                  ((IClientChannel)wcfClient1).Close();
      11:                  myChannelFactory.Close();
      12:   
      13:                  //assert
      14:                  Assert.AreEqual(235, s);
      15:              }
      16:          }

    你可以DEBUG,在var responseMessag = proxy.ProcessMessage(requestMessage); 代码,可以看到Request与Response Message 文本:

    Request:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header>
        <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:30096/PassThroughService.svc</To>
        <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IMath/Add</Action>
      </s:Header>
      <s:Body>
        <Add xmlns="http://tempuri.org/">
          <A>1</A>
          <B>234</B>
        </Add>
      </s:Body>
    </s:Envelope>

    Response:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header />
      <s:Body>
        <AddResponse xmlns="http://tempuri.org/">
          <AddResult>235</AddResult>
        </AddResponse>
      </s:Body>
    </s:Envelope>

    从这里我们可以看到这是完整的消息包,所以使用这个代理Service,拦截消息体后,还可以做一些其它TASK。例如,存储,过滤等。

    希望这篇POST对您开发WCF有帮助。


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    Angular4 后台管理系统搭建(5)
    Angular4 后台管理系统搭建(4)
    Angular4 后台管理系统搭建(3)
    Angular4 后台管理系统搭建(2)
    Angular4 后台管理系统搭建(1)
    训练x_vector时kaldi的模型选择机制
    investment
    拉单杠
    programming blogs
    pronunciation from longman 718
  • 原文地址:https://www.cnblogs.com/wintersun/p/2134959.html
Copyright © 2011-2022 走看看