標籤: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服務