微軟 WCF的幾種寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服務

來源:互聯網
上載者:User

標籤:cmd   成功   reg   point   public   partial   pac   cte   設定   

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" -ipause

卸載指令碼

"WcfService_HostWinService.exe" -upause

順利執行指令碼後,服務列表裡面就增加一個服務項目了。

卸載操作,直接執行指令碼就會卸載服務,非常方便哦。

 

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介面,就是一種非常方便的調用了。

 

微軟 WCF的幾種寄宿方式,寄宿IIS、寄宿winform、寄宿控制台、寄宿Windows服務

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.