WCF寄宿方式

WCF开发框架形成之旅---WCF的几种寄宿方式

WCF寄宿方式是一种非常灵活的操作,可以在IIS服务、Windows服务、Winform程序、控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便、高效提供服务调用。本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解。

1、 WCF服务的IIS服务寄宿

我在我前面几篇WCF开发框架的介绍文章中,介绍过了WCF常用的一种寄宿方式,IIS服务寄宿。这种寄宿方式是最为方便的方式,而且由于服务只需要IIS运行就能自动运行起来,因此广为使用。

创建这种方式IIS寄宿方式的,只需要在解决方案里面,添加WCF服务应用程序,就可以生成这种的服务模块了。

这个是一个基于Web的应用程序,创建项目后会生成一个Service1.svc的服务页面,以及相关的WCF服务接口和实现,如下图所示。

这个就是简单的WCF服务,当然如果是复杂的实际应用,会考虑和数据库打交道,而且可能项目会分成几个进行管理,从而实现更好的逻辑分离操作。

2、 创建WCF服务库为多种寄宿做准备

除了上面常用的IIS服务寄宿,一般还会有各种各样的寄宿方式,不过如果采用其他方式的寄宿方式,一般会把WCF服务和寄宿方式进行项目的分离,实现更好的重用操作,特别WCF需要考虑多种寄宿方式的情况下。下面是WCF服务库和WCF服务应用程序的介绍说明,先了解一下基础。

WCF服务库,可以认为是一个包含WCF服务以及契约定义的类库。这里WCF服务库还不能直接运行,你可以在其他项目里引用,在宿主里启用托管这个库。

而WCF应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定义,可以直接看到运行的效果。此项目模板应该是基于IIS托管的程序。

前者一般考虑WCF服务设计的时候,服务类的定义为单独的库,可以为其它项目使用。提高代码的复用性。后者在开发基于IIS托管的WCF服务程序时,比较多见,自学的时候也可以使用这种类型。当然你也可以修改这些代码,比如把WCF服务程序里的类,移到一个单独的类库里。

创建WCF服务库,可以理解为我们开发.NET程序时创建的一个类库模块,不含界面,如下所示,创建一个WCF服务库。

确定后就只有一个示例服务Service1生成了。

这里,我们为了演示,就不修改任何它们的代码,原始的代码如下所示。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceLibrary
{
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
}

3、 WCF服务的控制台程序寄宿

这种也是一种常见的WCF服务寄宿方式,通过启动一个类似DOS窗口的控制台软件,实现WCF服务的动态寄宿,关闭控制台程序,服务就自然终止。

这种方式很简单,创建一个控制台程序,然后添加WCF服务类库的项目应用,在Main函数里面添加下面代码即可实现。

namespace WcfService_HostConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ServiceHost serviceHost = new ServiceHost(typeof(Service1));
                if (serviceHost.State != CommunicationState.Opened)
                {
                    serviceHost.Open();
                }

                Console.WriteLine("WCF 服务正在运行......");
                Console.WriteLine("输入回车键 <ENTER> 退出WCF服务");
                Console.ReadLine();
                serviceHost.Close();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
    }
}

4、 WCF服务的Winform程序寄宿

和控制台程序一样,我们创建一个Winform项目,然后在窗体启动代码里面添加寄宿方式的代码即可,为了较好的响应体验,可以使用后台线程程序进行服务启动,如下所示。

namespace WcfService_HostWinform
{
    public partial class FrmMain : Form
    {
        ServiceHost serviceHost = null;
        BackgroundWorker worker = null;

        public FrmMain()
        {
            InitializeComponent();

            worker = new BackgroundWorker();
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);

            if (!worker.IsBusy)
            {
                tssTips.Text = "正在启动......";
                lblTips.Text = tssTips.Text;
                worker.RunWorkerAsync();
            }
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                serviceHost = new ServiceHost(typeof(Service1));
                if (serviceHost.State != CommunicationState.Opened)
                {
                    serviceHost.Open();
                }

                e.Result = "正常";
            }
            catch (Exception ex)
            {
                e.Result = ex.Message;
            }
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                if (e.Result.ToString() == "正常")
                {
                    tssTips.Text = "服务正在进行侦听......";
                }
                else
                {
                    tssTips.Text = string.Format("错误:{0}", e.Result);
                }

                lblTips.Text = tssTips.Text;
            }
        }
        ...........................
    }
}

当然为了防止Winform程序被不小心关闭,可以添加托盘代码,把程序缩小到托盘图标里面。

5、 WCF服务的Windows 服务程序寄宿

这种方式的服务寄宿,和IIS一样有一个一样的优点,系统启动后,WCF服务也会跟着启动了,不用人工干预,也是一种较好的寄宿方式。

为了实现这种方式的寄宿,我们创建一个控制台程序,然后添加响应的Window服务和安装程序类

然后在服务类启动里面添加WCF的寄宿代码,如下所示。

    public class ServiceManager : ServiceBase
    {
        private static object syncRoot = new Object();//同步锁
        private ServiceHost serviceHost = null; //寄宿服务对象

        public ServiceManager()
        {
            this.ServiceName = Constants.ServiceName;
        }

        /// <summary>
        /// 设置具体的操作,以便服务可以执行它的工作。
        /// </summary>
        protected override void OnStart(string[] args)
        {
            try
            {
                serviceHost = new ServiceHost(typeof(Service1));
                if (serviceHost.State != CommunicationState.Opened)
                {
                    serviceHost.Open();
                }
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
            }

            LogTextHelper.Info(Constants.ServiceName + DateTime.Now.ToShortTimeString() + "已成功调用了服务一次。");

            LogTextHelper.Info(Constants.ServiceName + "已成功启动。");
        }

为了实现通过该控制台程序实现参数化安装和卸载服务,我们需要拦截控制台的参数,并进行相应的操作,如下所示。

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            ServiceController service = new ServiceController(Constants.ServiceName);

            // 运行服务
            if (args.Length == 0)
            {
                ServiceBase[] ServicesToRun;
                ServicesToRun = new ServiceBase[] { new ServiceManager() };
                ServiceBase.Run(ServicesToRun);
            }
            else if (args[0].ToLower() == "/i" || args[0].ToLower() == "-i")
            {
                #region 安装服务
                if (!ServiceIsExisted(Constants.ServiceName))
                {
                    try
                    {
                        string[] cmdline = { };
                        string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;

                        TransactedInstaller transactedInstaller = new TransactedInstaller();
                        AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
                        transactedInstaller.Installers.Add(assemblyInstaller);
                        transactedInstaller.Install(new System.Collections.Hashtable());

                        TimeSpan timeout = TimeSpan.FromMilliseconds(1000 * 10);
                        service.Start();
                        service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                    }
                    catch (Exception ex)
                    {
                        LogTextHelper.Info(ex);
                        throw;
                    }
                }
                #endregion
            }
            else if (args[0].ToLower() == "/u" || args[0].ToLower() == "-u")
            {
                #region 删除服务
                try
                {
                    if (ServiceIsExisted(Constants.ServiceName))
                    {
                        string[] cmdline = { };
                        string serviceFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;

                        TransactedInstaller transactedInstaller = new TransactedInstaller();
                        AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
                        transactedInstaller.Installers.Add(assemblyInstaller);
                        transactedInstaller.Uninstall(null);
                    }
                }
                catch (Exception ex)
                {
                    LogTextHelper.Info(ex);
                    throw;
                }
                #endregion
            }
        }

编译程序成功后,我们添加两个批处理的DOS脚本来实现执行程序的自动安装和卸载,如下所示。

安装脚本

"WcfService_HostWinService.exe" -i
pause

卸载脚本

"WcfService_HostWinService.exe" -u
pause

顺利执行脚本后,服务列表里面就增加一个服务项目了。

卸载操作,直接执行脚本就会卸载服务,非常方便哦。

6、 WCF服务的Web寄宿

当然,除了以上几种方式,这种以WCF服务库的方式,也可以在Web方式进行寄宿(IIS方式),这种方式更简单,添加一个后缀名的svc的文件,只需要一行代码即可,如下所示。

7、 使WCF服务支持GET方式调用

有时候,我们为了需要,可能通过一个小程序发布一个服务,然后供其他程序进行调用,可能是Web,也可以是Winform,但是我们是想提供一个基于HTTP,GET或者POST方式来实现接口的调用的,例如,提供一个JSON格式或者文本格式的内容返回操作。

如果是整合在Winform里面,那么我们在Winform里面添加一个WCF的项,修改里面的代码就可以了,如下所示。

首先要在使用GET方式的WCF服务接口的添加说明。如果是POS方式,增加设置有点不同([WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)])。

namespace WcfServiceForWinform
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        void DoWork();

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
        string GetData(int value);
    }
}

第二,在实现类里面添加相应的设置

namespace WcfServiceForWinform
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1 : IService1
    {
        public void DoWork()
        {
        }

        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
    }
}

配置文件如下所示,颜色标注特别的要注意:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true"/>
  </system.web>

  <system.serviceModel>
    <services>
      <service name="WcfServiceForWinform.Service1"  behaviorConfiguration="ServiceConfig">
        <endpoint address="" binding="webHttpBinding"
                  bindingConfiguration="webHttpBindingWithJsonP" behaviorConfiguration="webHttpBehavior"
                  contract="WcfServiceForWinform.IService1">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9000/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"  />
      </webHttpBinding>
    </bindings>

    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>

      <serviceBehaviors>
        <behavior name="ServiceConfig">
          <serviceMetadata httpGetEnabled="True" policyVersion="Policy15"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

运行Winform程序,启动了WCF服务后,我们可以在浏览器(Chrome)上进行操作,如下结果所示。

从上图我们可以看到,这个通过Winform启动起来的WCF服务,连接也能通过GET方式进行接口调用了,接口可以通过参数进行传递,对于一些方便传输数据的接口如JSON接口,就是一种非常方便的调用了。

以上轉http://i.cnblogs.com/EditPosts.aspx?opt=1

时间: 2024-08-03 23:39:17

WCF寄宿方式的相关文章

WCF 寄宿方式 代码,配置文件

可以通过代码或者配置文件寄宿WCF服务,在使用过程中的一些心得,记录一下,方便后续查阅. 预备知识,几个地址的作用 1. behavior.HttpGetUrl  定义元数据的地址,如果不定义基地址,则必须定义HttpGetUrl ,是The absolute or relative location of the metadata. 2.baseAddresses 服务的地址,因为元数据(metadata)是属于一个host的,并不属于一个endpoint.此基地址就是客户端添加服务引用的地址

[转]WCF的几种寄宿方式

转自:WCF开发框架形成之旅---WCF的几种寄宿方式 WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解. 1. WCF服务的IIS服务寄宿 我在我前面几篇WCF开发框架的介绍文章中,介绍过了WCF常用的一种寄宿方式,IIS服务寄宿.这种寄宿方式是最为方便的方式,而且由于服务

微软 WCF的几种寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服务

WCF寄宿方式是一种非常灵活的操作,可以在IIS服务.Windows服务.Winform程序.控制台程序中进行寄宿,从而实现WCF服务的运行,为调用者方便.高效提供服务调用.本文分别对这几种方式进行详细介绍并开发例子进行说明,以求大家对WCF寄宿的方式进行全面的认识和了解. 1. WCF服务的IIS服务寄宿 我在我前面几篇WCF开发框架的介绍文章中,介绍过了WCF常用的一种寄宿方式,IIS服务寄宿.这种寄宿方式是最为方便的方式,而且由于服务只需要IIS运行就能自动运行起来,因此广为使用. 创建这

WCF引用方式之IIS方式寄宿服务

通过IIS方式寄宿服务 之前的例子是将控制台作为WCF的寄宿方式或者是直接添加契约项目的引用,然后通过配置或者是ChannelFactory的形式进行创建服务对象,其实在大多的开发中以IIS的形式创建WCF也是比较常见的.每一个Webservice都是具有一个asmx文本文件,客户端通过访问.asmx文件即可实现Webservice的调用.当然WCF和Webservice类似,每一个WCF服务都有一个对应的.svc文本文件.基于IIS服务寄宿要求的WCF服务都具有相应的.svc文件,.svc文件

将WCF寄宿在托管的Windows服务中

在我之前的一篇博客中我介绍了如何发布WCF服务并将该服务寄宿于IIS上,今天我再来介绍一种方式,就是将WCF服务寄宿在Windows服务中,这样做有什么好处呢?当然可以省去部署IIS等一系列的问题,能够让部署更加简单,当然WCF的寄宿方式一般分为以下四种方式,针对每一种方式我来简单介绍以下: 具体的寄宿方式详细信息请参考MSDN:https://msdn.microsoft.com/zh-cn/library/ms733109(v=vs.100).aspx 一.WCF服务寄宿方式: 1):寄宿在

WCF寄宿与IIS里时遇到的问题

[问题总结]WCF寄宿与IIS里时遇到的问题 最近在公司做了一个小的视频处理网站,由于视频处理,网站在不同的服务器上,所以处理视频的时候得在网站服务器上通过wcf请求视频处理服务器处理视频,并将结果返回.我在写好这个wcf服务后寄宿到IIS里时遇到了不少的问题,下面是问题的描述,以及解决的方法. 问题1: 由于我这里的wcf服务是采用“WSHttpBinding”的方式,即安全绑定模式,客户端在引用这个服务后所生成的终结点配置(endpoint )就变成了 <endpoint address=&qu

WCF寄宿(Host)之自我寄宿(Self-Hosting)简单实例【Windows应用程序宿主】

 前言: 以各种应用程序做自我寄宿的宿主原理方法大同小异,故:这儿直接上案例! 步骤一:创建服务契约和服务 1.新建解决方案:添加WCF服务库项目. 2.为了演示,我把自动生成的接口以及实现接口的类删除,自己添加一个WCF Service 3.撰写服务函数(同时,因为将原有的自动生成的接口与类删除了,故而需要将配置文件作相应的改动:) namespace wcfself02{ // NOTE: You can use the "Rename" command on the "

WCF发布方式介绍

转载出处:http://blog.csdn.net/fangxing80/article/details/6101790 从VS2005推出WCF以来,WCF逐步取代了Remoting, WebService成为.NET上分布式程序的主要技术.WCF统一的模型整合了以往的 WebService.Remoting.MSMQ 等技术,让分布式开发变得更加简单,方便,快捷. wcf_host_architecture (上图选自<Programming WCF Services>) WCF基本概念(

WCF学习之旅—WCF寄宿前的准备(八)

一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有"WCF 服务应用程序"和"WCF服务库". WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类协定的定义,可以直接看到运行的效果. WCF服务库,可以认为是一个包含WCF服务以及协定定义的类库.不能直接运行,你可以在其他项目里引用,在宿主里启用托管这个库,有点类似于我们在Web/windows项目中应用的类库.考虑WCF服务设计的时候,服务类的定义为单独的库,可以为其它