• WCF宿主实践入门


    本篇属于WCF实践入门,由于博主本人水平有限,没有理论上的介绍,仅仅从其几种不同的宿主方式分别介绍WCF的使用。


    WCF有多种宿主方式:1、自托管宿主,2、windows service宿主,3、IIS宿主,4、WAS宿主

    本篇一一进行简要介绍(win7 + vs2012)。


    一、自托管宿主

    利用WCF提供的ServiceHost<T>提供的Open()和Close()方法。

    • 新建WCF服务库
    • 新建WCF宿主应用程序

    1)新建一个解决方案,名称为WcfService1Study。新建一个WCF服务库如下图:

    2)我们将接口和类名分别重命名IDataService和DataService(读者自便),简化其中代码如下(只是为了实验而已)

    //IDataService.cs
    namespace WcfServiceLibrary
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
        [ServiceContract]
        public interface IDataService
        {
            [OperationContract]
            CompositeType GetData();
        }
    
        // 使用下面示例中说明的数据约定将复合类型添加到服务操作。
        // 可以将 XSD 文件添加到项目中。在生成项目后,可以通过命名空间“WcfServiceLibrary.ContractType”直接使用其中定义的数据类型。
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
    
            [DataMember]
            public bool BoolValue
            {
                get { return boolValue; }
                set { boolValue = value; }
            }
    
            [DataMember]
            public string StringValue
            {
                get { return stringValue; }
                set { stringValue = value; }
            }
        }
    }
    View Code
    //DataService.cs
    namespace WcfServiceLibrary
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
        public class DataService : IDataService
        {
            public CompositeType GetData()
            {
                //仅仅返回一个类
                return new CompositeType();
            }
        }
    }
    View Code

    到此,我们的WCF类库已经建好了。

    3)修改App.config

    默认在不修改配置文件的情况下,vs会自动给我们的服务配置到一个端口,如下  http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/ 

    我们修改App.config如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
      </system.web>
      <!-- 部署服务库项目时,必须将配置文件的内容添加到 
      主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
      <system.serviceModel>
        <services>
          <service name="WcfServiceLibrary.DataService">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8081/WcfServiceLibrary/DataService/" />
              </baseAddresses>
            </host>
            <!-- Service Endpoints -->
            <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
            <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService">
              <!-- 
                  部署时,应删除或替换下列标识元素,以反映
                 用来运行所部署服务的标识。删除之后,WCF 将
                  自动推断相应标识。
              -->
              <identity>
                <dns value="localhost"/>
              </identity>
            </endpoint>
            <!-- Metadata Endpoints -->
            <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> 
            <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
            <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>-->
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,
              请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
              <!-- 要接收故障异常详细信息以进行调试,
              请将以下值设置为 true。在部署前设置为 false 
                以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="False" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    </configuration>
    View Code

    主要改动是服务地址的改动和约束(因为我们的类重命名了)的改动

     <baseAddresses>
                <add baseAddress="http://localhost:8081/WcfServiceLibrary/DataService/" />
       </baseAddresses>
    <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService">

    vs2012集成了wcf的测试客户端,ctrl+F5即可启动并测试wcf服务,效果如下:

    注意这里的【配置文件】菜单,里面包含有客户端对应的配置信息,接下来我们会用到。

    到这里,我们的WCF库已经建好、配置好,也测试通过了。接下来建立宿主程序。

    4)新建一个ConsoleApplication,命名为ConsoleAppSelfHost,增加对刚刚建好的WCF库的项目引用。

    添加 System.ServiceModel引用,修改代码如下:

    using System.ServiceModel;
    
    namespace ConsoleAppSelfHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary.DataService)))
                {
                    host.Open();
    
                    Console.WriteLine("wcf data service is running!");
                    Console.Read();//阻塞宿主程序结束,期间供客户端调用该wcf服务
    
                    host.Close();
                }
            }
        }
    }
    View Code

    5)修改ConsoleApplication的App.config,将第三步中标红文字操作的内容拷贝到配置文件即可。

    6)测试运行,如下:

    查了好久都没有找到解决方案~~~最后仔细看了下这个错误,“未经处理的异常: System.InvalidOperationException: 服务“WcfServiceLibrary.DataService”有零个应用程序(非基础结构)终结点。这可能是因为未找到应用程序的配置文件,或者在配置文件中未找到与服务名称匹配的服务元素,或者服务元素中未定义终结点。”,问题是出在配置文件,我试着将WCF服务库的配置文件中的services节点拷贝到宿主程序配置中,测试,通过!

    我的理解:在这种自宿主方式下,WCF服务库的配置文件其实只是用来测试的,其能真正对外服务则需要宿主程序进行配置,即宿主程序就是服务端,而WCF服务库在这种方式下其实就是一个类库,仅仅提供dll即可。

    经过修改,最终宿主程序的配置文件如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
      <system.serviceModel>
        <services>
          <service name="WcfServiceLibrary.DataService">
            <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService">
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8081/WcfServiceLibrary/DataService/" />
              </baseAddresses>
            </host>
          </service>
        </services>
    
        <client>
          <endpoint address="http://localhost:8081/WcfServiceLibrary/DataService/" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService"></endpoint>
        </client>
      </system.serviceModel>
    </configuration>
    View Code

    运行,通过,大功告成。通过宿主Console窗口可以查看效果(在宿主运行期间,即wcf服务打开的时候,通过WCF的地址也可查看wsdl)。

    二、windows service宿主

    Windows Service宿主的实现就是依赖Windows Service项目,在Windows服务类(继承了ServiceBase类)的OnStart()和OnStop()方法中启动和关闭WCF服务的功能。

    1)继续使用上述的WCF服务类库

    2)新建一个windows service项目,命名为WindowsServiceHost,增加对刚刚建好的WCF库的项目引用。

    添加 System.ServiceModel引用,重命名Service1为WCFService,代码如下:

    namespace WindowsServiceHost
    {
        public partial class WCFService : ServiceBase
        {
            ServiceHost _host = null;
            public WCFService()
            {
                InitializeComponent();
            }
    
            protected override void OnStart(string[] args)
            {
                if (_host != null)
                {
                    _host.Close();
                    _host = null;
                }
                _host = new ServiceHost(typeof(WcfServiceLibrary.DataService));
                _host.Open();
            }
    
            protected override void OnStop()
            {
                if (_host != null)
                {
                    _host.Close();
                    _host = null;
                }
            }
        }
    }
    View Code

    3)配置文件和自宿主方式一样。

    4)增加安装包程序

    在WCFService的设计模式下右键【添加安装程序】即可。

    5)我们通过在Visual Studio的Command Prompt模式下运行如下命令:

    E:	estProjectsWcfService1StudyWindowsServiceHostinDebug>InstallUtil WindowsServiceHost.exe

    即可完成对服务宿主的安装。

    6)在新安装的windows服务没有启动的时候,我们查看WCF的wsdl(配置的地址 http://localhost:8081/WcfServiceLibrary/DataService/)是无法访问的,当启动该服务之后,即可成功访问,说明Wcf服务成功寄宿在windows服务内。

    三、IIS宿主

    IIS宿主的使用相当简单。

    1)新建wcf 服务应用程序,该应用程序可以被发布到IIS,即可完成IIS的寄宿。

    本人修改了项目中的IService.cs为IMyWcfService.cs,Service.svc为MyWcfService.svc,CompositeType为MyWcfClass,读者自行随意修改。

    我们将其发布地址设置为:http://127.0.0.1/WcfService1Study/

    访问http://127.0.0.1/WcfService1Study/MyWcfService.svc,即可看到wsdl内容。

    2)新建web应用程序,添加服务引用(wcf地址 http://127.0.0.1/WcfService1Study/MyWcfService.svc)即可调用wcf了。

    web.config的内容都是自动添加的,每次更新服务应用,web.config也会更新。

    四、WAS宿主

    博主还没有对WAS宿主的大体认识,故借鉴大牛博客介绍如下:

    WAS是IIS 7.0的一部分,但也可以独立地安装与配置。WAS支持所有可用的WCF传输协议、端口与队列。
    利用WAS托管服务与IIS宿主托管服务的方法并没有太大的区别,仍然需要创建svc文件,同时在IIS中需要在站点中创建应有程序指向托管应用程序,还可以设置访问服务的别名与应用程序池。
    由于WAS诉诸支持所有的绑定,因此此时的服务绑定并不会受到宿主的限制。


    到此,四种宿主方式简单实践入门就完成了。

    博主水平有限,理论知识有待提升,望和诸位博友共同学习进步。

  • 相关阅读:
    WordPress插入图片无法居中的解决方法
    wordpress文章显示同一分类下的上一篇下一篇
    git4
    git3
    git2
    git1
    百度地图vue版本标记点拖拽事件传参问题
    postcss-plugin-px2rem的使用
    保留小数位toFixed()方法的怪异表现
    大公司是怎样开发和部署前端代码(转张云龙大神的回答)
  • 原文地址:https://www.cnblogs.com/cotton/p/4349737.html
Copyright © 2020-2023  润新知