• 【WCF--初入江湖】01 WCF编程概述


    01 WCF编程概述

    SOA的优点

    1.服务独立于平台和工作环境。服务并不关心自己所处的环境,也不关心与之进行通信的服务所处的    环境。
    2.服务相互隔离。
    3.服务对协议、格式和传输中立。
    4.服务可以扩展。
    5.服务行为不受限制。
     
     
    实现SOA思想的技术:
        1.webService
        2.WCF
     
     
    什么是WCF
     
    MSDN上的定义:
             WCF为.NetFramework 提供了一个基础,使其能够编写代码,以在组件、应用程序、系统之间进行通信。WCF的设计遵循的是面向服务的原则。服务是指可以通过消息与之进行交互的一段代码。服务是被动的。它们等待传入消息之后才开始工作。客户端是发起者,客户端将消息发送给服务来请求工作。
     
     
     http://www.cnblogs.com/lykbk/archive/2013/03/18/56445fdgbhfg894548.html

    WCF

      是微软分布式应用程序开发的集大成者,它整合了.Net平台下所有的和分布式系统有关的技术,如

         Enterprise Sevices

      (COM+).Net Remoting(一种非常有弹性的扩展性框架)、

         Web Service(ASMX)、

       WSE3.0

      MSMQ消息队列。

    以通信(Communiation)范围而论,它可以

      跨进程、跨机器、跨子网、企业网乃至于 Internet;

    以宿主程序而论,可以以

      ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)

    WCF可以支持的协议包括TCP,

    HTTP,跨进程以及自定义,

    安全模式则包括SAML, Kerberos,X509,用户/密码,

    自定义等多种标准与模式。

    也就是说,在WCF框架下,开发基于SOA的分布式系统变得容易了,微软将所有与此相关的技术要素都包含在内,掌握了WCF,就相当于掌握了叩开SOA大门的钥匙

     
     
     
     
    WCF与webService是什么关系
     
    什么是Web Service
     
     异构平台互操作技术:
        webService

    ASP.NET Web Service:

        利用Soap协议对象在分布式环境之间的数据交互。

               WSDL来发布服务接口相关的描写。

    称为WSE系列:

             ASP.NET Web Service的安全,功能,数据加密、解密,托管宿主等多方面的伸展,

     
     
     
     http://www.cnblogs.com/lykbk/archive/2013/03/18/56445fdgbhfg894548.html
     http://blog.sina.com.cn/s/blog_698853780100sitx.html
     
     WCF 能够创建兼容 Web 服务的服务,也就是说可以创建能够与Web 服务互联互通的服务,他们两个并不能用简单包含或者等同关系来表述。
     WCF 是一套框架,用来创建各种服务。其中包括创建 Web服务(采用 basicHttpBinding绑定的服务就是一个Web 服务)。
     
    WCF是用于开发WS的框架,但又不仅限于开发WS应用,它还通过扩展以支持编写普通的Socket应用程序.
     
    WCF与WS的区别:
      (1)WCF可以不依赖于IIS。
      (2)WCF可以配置成BasicHttpBinding来兼容(或者说变身成)WS。
      (3)WCF可以基于TCP或者MessegeQueue来传输数据。
      (4)WCF的可配置性比WS强,比如安全性。
      (5)WCF可以是有状态的,并支持事务。。
     
     ------------------------
    WCF可使用Web服务进行通信,因此与同样支持SOAP的其他平台(例如基于J2EE的主流应用程序服务器)间的互操作性就变得简单明了。
    还可以对WCF进行配置和扩展,以便与使用并非基于SOAP的消息的Web服务进行通信。
    性能是大多数业务中至关重要的考虑事项。开发WCF的目标就是要使之成为Microsoft所开发的速度最快的分布式应用程序平台之一。
     
     
    WCF宿主

    static void Main(string[] args) { var baseAddress = ConfigurationManager.AppSettings["baseAddress"]; ApplicationService.Initialize(); MongoDBBootstrapper.Bootstrap(); using (ServiceHost orderService = new ServiceHost(typeof(OrderService), new Uri(string.Format("{0}/OrderService.svc", baseAddress)))) using (ServiceHost productService = new ServiceHost(typeof(ProductService), new Uri(string.Format("{0}/ProductService.svc", baseAddress)))) using (ServiceHost userService = new ServiceHost(typeof(UserService), new Uri(string.Format("{0}/UserService.svc", baseAddress)))) { orderService.Open(); productService.Open(); userService.Open(); Console.WriteLine("Byteart Retail Services started at: {0}.", DateTime.Now); Console.ReadLine(); Console.WriteLine("Byteart Retail Services stopped at: {0}.", DateTime.Now); orderService.Close(); productService.Close(); userService.Close(); } }
      <appSettings>
        <add key="baseAddress" value="http://localhost:8559"/>
      </appSettings>

    服务端配置:

     <system.serviceModel>
        <extensions>
          <behaviorExtensions>
            <add name="unity" type="ByteartRetail.Infrastructure.UnityExtensions.UnityBehaviorExtensionElement, ByteartRetail.Infrastructure,  Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          </behaviorExtensions>
        </extensions>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
              <unity operationContextEnabled="true" instanceContextEnabled="true" contextChannelEnabled="true" serviceHostBaseEnabled="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>

    另一种配置,

    namespace Keasy5.WCF.WCFHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost serviceHostPerCall = new ServiceHost(typeof(ServicePerCall)))
                using (ServiceHost serviceHostPerSession = new ServiceHost(typeof(ServicePerSession)))
                using (ServiceHost serviceHostSingle = new ServiceHost(typeof(ServiceSingle)))
                {
                    serviceHostPerCall.Open();
                    serviceHostPerSession.Open();
                    serviceHostSingle.Open();
    
                    Console.WriteLine("所有服务已经启动: {0}.", DateTime.Now);
                    Console.ReadLine();
                    Console.WriteLine("所有服务已经关闭: {0}.", DateTime.Now);
    
                    serviceHostPerCall.Close();
                    serviceHostPerSession.Close();
                    serviceHostSingle.Close();
                }
            }
        }
    }

      对应的配置文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <system.web>
        <compilation debug="true" />
      </system.web>
      <system.serviceModel>
        <services>
          <service name="Keasy5.WCF.WCFService.ServicePerCall" behaviorConfiguration="textserviceBehaviors">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:5833/Keasy5.WCF.WCFService/ServicePerCall/" />
              </baseAddresses>
            </host>
            <endpoint name="ServicePerCall" address="" binding="basicHttpBinding" contract="Keasy5.WCF.WCFService.IService1"></endpoint>
          </service>
    
          <service name="Keasy5.WCF.WCFService.ServicePerSession" behaviorConfiguration="textserviceBehaviors">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:5833/Keasy5.WCF.WCFService/ServicePerSession/" />
              </baseAddresses>
            </host>
            <endpoint name="" address="" binding="basicHttpBinding" contract="Keasy5.WCF.WCFService.IService1"></endpoint>
          </service>
    
          <service name="Keasy5.WCF.WCFService.ServiceSingle" behaviorConfiguration="textserviceBehaviors">
            <host>
              <baseAddresses>
                <add baseAddress = "http://localhost:5833/Keasy5.WCF.WCFService/ServiceSingle/" />
              </baseAddresses>
            </host>
            <endpoint name="ServiceSingle" address="" binding="basicHttpBinding" contract="Keasy5.WCF.WCFService.IService1"></endpoint>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors >
            <behavior name="textserviceBehaviors">
              <serviceMetadata httpGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="True" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>
    View Code

     客户端调用

    获取WCF服务的一个封装类:

    ServiceProxy.cs

    using System.ServiceModel;
    
    namespace ByteartRetail.Infrastructure.Communication
    {
        /// <summary>
        /// 表示用于调用WCF服务的客户端服务代理类型。
        /// </summary>
        /// <typeparam name="T">需要调用的服务契约类型。</typeparam>
        public sealed class ServiceProxy<T> : DisposableObject
            where T : class, IApplicationServiceContract
        {
            #region Private Fields
            private T client = null;
            private static readonly object sync = new object();
            #endregion
    
            #region Protected Methods
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                    lock (sync)
                    {
                        Close();
                    }
            }
            #endregion
    
            #region Public Properties
            /// <summary>
            /// 获取调用WCF服务的通道。
            /// </summary>
            public T Channel
            {
                get
                {
                    lock (sync)
                    {
                        if (client != null)
                        {
                            var state = (client as IClientChannel).State;
                            if (state == CommunicationState.Closed)
                                client = null;
                            else
                                return client;
                        }
                        var factory = ChannelFactoryManager.Instance.GetFactory<T>();
                        client = factory.CreateChannel();
                        (client as IClientChannel).Open();
                        return client;
                    }
                }
            }
            #endregion
    
            #region Public Methods
            /// <summary>
            /// 关闭并断开客户端通道(Client Channel)。
            /// </summary>
            /// <remarks>
            /// 如果使用using语句对ServiceProxy进行了包裹,那么当程序执行点离开using的
            /// 覆盖范围时,Close方法会被自动调用,此时客户端无需显式调用Close方法。反之
            /// 如果没有使用using语句,那么则需要显式调用Close方法。
            /// </remarks>
            public void Close()
            {
                if (client != null)
                    ((IClientChannel)client).Close();
            }
            #endregion
        }
    }
    View Code

    ChannelFactoryManager.cs

    using System;
    using System.Collections.Generic;
    using System.ServiceModel;
    
    namespace ByteartRetail.Infrastructure.Communication
    {
        /// <summary>
        /// 表示Channel Factory管理器。
        /// </summary>
        internal sealed class ChannelFactoryManager : DisposableObject
        {
            #region Private Fields
            private static readonly Dictionary<Type, ChannelFactory> factories = new Dictionary<Type, ChannelFactory>();
            private static readonly object sync = new object();
            private static readonly ChannelFactoryManager instance = new ChannelFactoryManager();
            #endregion
    
            #region Ctor
            static ChannelFactoryManager() { }
            private ChannelFactoryManager() { }
            #endregion
    
            #region Public Properties
            /// <summary>
            /// 获取<c>ChannelFactoryManager</c>的单件(Singleton)实例。
            /// </summary>
            public static ChannelFactoryManager Instance
            {
                get { return instance; }
            }
            #endregion
    
            #region Protected Methods
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    lock (sync)
                    {
                        foreach (Type type in factories.Keys)
                        {
                            ChannelFactory factory = factories[type];
                            try
                            {
                                factory.Close();
                                continue;
                            }
                            catch
                            {
                                factory.Abort();
                                continue;
                            }
                        }
                        factories.Clear();
                    }
                }
            }
            #endregion
    
            #region Public Methods
            /// <summary>
            /// 获取与指定服务契约类型相关的Channel Factory实例。
            /// </summary>
            /// <typeparam name="T">服务契约的类型。</typeparam>
            /// <returns>与指定服务契约类型相关的Channel Factory实例。</returns>
            public ChannelFactory<T> GetFactory<T>()
                where T : class, IApplicationServiceContract
            {
                lock (sync)
                {
                    ChannelFactory factory = null;
                    if (!factories.TryGetValue(typeof(T), out factory))
                    {
                        factory = new ChannelFactory<T>(typeof(T).Name);
                        factory.Open();
                        factories.Add(typeof(T), factory);
                    }
                    return factory as ChannelFactory<T>;
                }
            }
            #endregion
        }
    }
    View Code

    客户端调用:

               using (ServiceProxy<IProductService> proxy = new ServiceProxy<IProductService>())
                {
                    var categories = proxy.Channel.GetCategories(QuerySpec.Empty);
                    return View(categories);
                }

    客户端配置:

      注意到ChannelFactoryManager类中创建工厂的方法:

    public ChannelFactory<T> GetFactory<T>()
    {
    。。。。     factory
    = new ChannelFactory<T>(typeof(T).Name);

    注意到ChannelFactoryManager类中创建工厂的方法,使用的是类型的名称typeof(T).Name)作为节点的配置名。

    ChannelFactory<T>构造函数查看参数说明:

    //
    // 摘要: 
    // 使用指定的终结点配置名称初始化 System.ServiceModel.ChannelFactory<TChannel> 类的新实例。
    //
    // 参数: 
    // endpointConfigurationName:
    // 用于终结点的配置名称。
    //
    // 异常: 
    // System.ArgumentNullException:
    // endpointConfigurationName 为 null。
    public ChannelFactory(string endpointConfigurationName);
    View Code

    故,客户端的配置EndPointd配置节点名要使用要用类型的名称,

    <endpoint name="IProductService" 。。。

    例如:

    <endpoint name="IProductService" address="http://localhost:8558/ProductService.svc" contract="ByteartRetail.ServiceContracts.IProductService" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
    
    

    客户端的配置:

      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="ServiceProxyBinding" sendTimeout="00:10:00" receiveTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="134217728" maxBufferSize="134217728">
              <readerQuotas maxStringContentLength="134217728" />
            </binding>
          </basicHttpBinding>
        </bindings>
        <client>
          <endpoint name="IProductService" address="http://localhost:8558/ProductService.svc" contract="ByteartRetail.ServiceContracts.IProductService" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
          <endpoint name="IOrderService" address="http://localhost:8558/OrderService.svc" contract="ByteartRetail.ServiceContracts.IOrderService" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
          <endpoint name="IUserService" address="http://localhost:8558/UserService.svc" contract="ByteartRetail.ServiceContracts.IUserService" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
          <endpoint name="IPostbackService" address="http://localhost:8558/PostbackService.svc" contract="ByteartRetail.ServiceContracts.IPostbackService" binding="basicHttpBinding" bindingConfiguration="ServiceProxyBinding" />
        </client>
      </system.serviceModel>
     
  • 相关阅读:
    Ubuntu中开启Telnet服务
    单片机串口通讯RXD与TXD如何对接详解
    KEIL, a Smart Comliler
    linux mail 命令(转载)
    VC程序在没装VC的机器中运行
    srand()以及rand()函数用法
    VC菜菜鸟:基于CFree的HelloWorld程序
    Keil使用中的若干问题(转)
    VMWARE 重新安装出错
    Linux个人学习笔记(编辑中)
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/3825355.html
Copyright © 2020-2023  润新知