WCF開發實戰

WCF開發實戰

 

一、 服務器應用開發

()    創建“WCF服務庫

文件(F)”->“新建項目(P)...”打開新建項目對話框。在左側的項目類型中選擇“WCF”,然後再在右側的模板中選擇“WCF服務庫
在下面的名稱文本框中,填寫我們要創建的WCF服務庫的項目名稱“WcfEmployee”


點擊確定,會創建出我們的WCF服務庫項目,在解決方案中會自動爲我們生成兩個類文件“IService1.cs”“Service1.cs”


這兩個類文件是兩個WCF示例文件,對我們開發沒有什麼用處,現在我們刪掉這兩個文件。

創建Employee實體類
解決方案窗口中,我們右擊Services項目名,選擇添加,再單擊

在彈出的添加新項窗口中,選擇,並在名稱文本框中寫入項名稱“Employee.cs”

爲Employee實體類編寫代碼
 

using System.Runtime.Serialization;

namespace WcfEmployee

{

 [DataContract]

public class Employee

    {

[DataMember]

        public string EmployeeId;

[DataMember]

        public string EmployeeName;

[DataMember]

        public int EmployeeAge;

    }

}


爲了保證此類在WCF調用中能夠被序列化,我們在Employee類上面加入[DataContract]標籤,在每個需要序列化的成員變量上加入[DataMember]標籤。這兩個標籤在使用的進候需要導入using System.Runtime.Serialization命名空間。
到此爲至,我們創建完了需要在服務中傳輸的複雜的數據類型Employee

創建服務接口
創建服務接口,聲明對外發布的類和方法。
解決方案窗口中,我們右擊WcfEmployee項目名,選擇添加,再單擊

在彈出的添加新項窗口中,選擇,並在名稱文本框中寫入項名稱“IEmployeeSrv.cs”


在此類文件中我們編寫服務接口,代碼如下:
using System.Collections.Generic;

using System.ServiceModel;

 

namespace WcfEmployee

{

  [ServiceContract]

public interface IEmployeeSrv

    {

  [OperationContract]

        void AddEmployees(Employee employee);

[OperationContract]

        List<Employee> GetAllEmployees();

 [OperationContract]

        void RemoveEmployee(string id);

 

    }

}

 


IEmployeeSrv接口上面,我們定義了[ServiceContract]標籤,此標籤代表此接口及實現此接口的類都是對外發布的Service類,在每個需要對外發布的方法上都加上[OperationContract]標籤,以使外部可以訪問到此方法。
[ServiceContract][OperationContract]這兩個標籤需要導入using System.ServiceModel命名空間。

創建實現服務接口的類
實現我們上面聲明的服務接口,實現對Employee的添加、刪除和檢索的具體功能。
解決方案窗口中,我們右擊WcfEmployee項目名,選擇添加,再單擊

在彈出的添加新項窗口中,選擇,並在名稱文本框中寫入項名稱“EmployeeSrv.cs”


在此類文件中編寫代碼實現IEmployeeSrv.cs服務接口。
 

 

using System.Collections.Generic;

using System.ServiceModel;

 

namespace WcfEmployee

{

 [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]

 

public class EmployeeSrv:IEmployeeSrv

    {

        List<Employee> _Employee=new List<Employee>();

public void AddEmployees(Employee employee)

        {

            employee.EmployeeId=Guid.NewGuid().ToString();

            _Employee.Add(employee);

        }

 

public void RemoveEmployee(string id)

        {

            Employee employee=_Employee.Find(p=>p.EmployeeId==id);

            _Employee.Remove(employee);

        }

 

public List<Employee> GetAllEmployees()

        {

            return _Employee;

        }

    }

}


此類是對IEmployeeSrv接口的具體實現,在此類的上面我們聲明瞭[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]標籤,此標籤代表這個類採用SingleTone(單類模式)來生成對象。
使用[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]接口需要導入using System.ServiceModel;命名空間。

 

app.configService1改爲EmployeeSrv.

運行WCF進行測試。
    VS2008中爲我們提供了測試WCF的工具,按F5啓動WCF會出現兩個東西
    一個是在右下角的托盤圖標中會出現WCFSVCHost(WCF服務主機),它爲我們在開發時候提供了一個運行WCF的服務器,用來爲測試客戶端提供WCF服務。


   
   
另一個是“WCF測試客戶端

   
    “
測試客戶端WcfSVCHost中取得WCF服務的元數據,解析爲右側的服務結構樹,從這裏面我們可以看到此WCF服務爲我們提供了一個服務契約“IEmployeeSrv”,此服務契約中對外提供了三個可調用的方法。
    雙擊AddEmployees()方法,我們可以從右面輸入相關的數據然後點擊調用,就可以把數據送給WCF服務器,去調用對應的方法了。

()   使用IIS發佈WCF服務
 上一篇中,我們創建了一個簡單的WCF服務,在測試的時候,我們使用VS2008自帶的WCFSVCHost(WCF服務主機)發佈WCF服務,以便進行測試。這種VS2008內置的WCFSVCHost只適用於開發人員測試的使用,能進行WCF服務部署。這一篇文章中我們來看一下如何在IIS中部發布我們上一篇中做好的WCF服務。

第一步:打開我們上一篇文章中建立的WCF服務項目。

 

 


圖《1

第二步:新建WCF服務站點。在解決方案上右擊,選擇添加”->“新建網站,打開新建網站對話框。在添加新網站對話框中,我們選擇“WCF服務,並把網站的名子命名爲“BookServiceHost”


圖《2
建立起來的新的WCF服務站點的結果如下,其中在App_Code文件中自動爲我們生成兩個類文件:IService.csService.cs。這兩個文件對我們來說沒有用,我們刪掉。

 


圖《3

第三步:在剛剛創建的WCF服務站點上添加對WCF服務庫項目--Services項目的引用。


圖《4

第四步:配置Service.svc文件。
雙擊Service.svc文件,我們可以看到它的聲明指示如下:
<%@ ServiceHost Language="C#" Debug="true" Service="Service" CodeBehind="~/App_Code/Service.cs" %>
由於在第二步中我們已經把IService.csService.cs兩個文件已經刪除了,所以這裏的聲明指示內容修改一下,讓這個Service.svc文件的後臺代碼指向我們上次創建的WCF服務庫項目--Services項目中的類,改後的代碼如下:
<%@ServiceHostLanguage="C#"Debug="true"Service="WcfEmployee.EmployeeSrv"%>
我們把其中的Service屬性指定爲WcfEmployee命名空間下的EmployeeSrv類,並把CodeBehind屬性刪去了。

第五步:配置此WCF服務站點與WCF服務庫項目之間的類的對應。
雖然在第三步中我們添加了對Services項目的引用,並且在第四步中修改了Service.svc的類的對應,但此時我們的WCF服務站點並不能把WCF服務庫中的服務和終結點發布出來,還需要我們對web.config進行一系列的配置工作。
web.config上右擊選擇編輯WCF配置

 



在彈出的服務配置編輯器窗口中,單擊新建服務...”

 

 

單擊”瀏覽”.定位到本項目下的Bin目錄,單擊WcfEmployee.dll,再選打開.

 

選”WcfEmployee.EmployeeSrv”,單擊”打開”

 

 

 

 

 

 

 


 

 


 


 


Service.svc上右擊,選擇在瀏覽器中查看,在IE中運行此服務。



由此我們看到我們可以在ASP.NET Development Server中發佈我們的WCF服務了。

第八步:在IIS佈署此WCF服務站點。
打開iis管理器,在其中找到一個正常的網站,如下圖中的wa3,右擊之,

 

別名任意,物理路徑必須準確爲項目所在的目錄.

使瀏覽器指向”http://localhost:83/EmployeeService/service.svc”,注意”EmployeeService”爲剛纔指定的別名.

 

在外網其他電腦上使瀏覽器指向”http://221.213.51.74:83/EmployeeService/service.svc

也應該出現上圖.

 

 

 

()   創建WCF服務宿主程序

1.    控制檯應用程序作爲宿主程序


 

建立控制檯應用程序ConsSrvHostEmployee

 

 


《圖1
ConsSrvHostEmployee程序中添加兩個引用:一個是WCF服務庫Services項目的引用,另一個是System.ServiceModel引用。

生成該項目。

 


ConsSrvHostEmployee 項目中的Program.cs中編寫代碼。
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using WcfEmployee;

using System.ServiceModel;

 

namespace ConsSrvHostEmployee

{

    class Program

    {

        static void Main(string[] args)

        {

            ServiceHost host = new ServiceHost(typeof(EmployeeSrv));

            host.Credentials.ServiceCertificate.SetCertificate("CN=OujianpingServer");

            host.Open();

            Console.WriteLine("服務已啓動......");

            Console.ReadLine();

            host.Close();

        }

    }

}

 

 

配置App.Config

 

App.Config上右擊選擇選擇編輯WCF配置,彈出服務配置管理窗口

 

 

 

 

 

 

 

 



第六步:點擊右邊的新建服務...”彈出新建服務元素嚮導窗口,單擊瀏覽按鈕,選擇Bin/Debug目錄下Services.dll程序集中的Services.EmployeeSrv服務。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

注意進行綁定配置,選擇“NewBinding0 netTcpBinding”。

 

 

 

 

 

 

 

 

配置元數據終結點:

//如果沒有這個過程,也可以正常啓動服務,但客戶端無法通過引用添加服務引用”.

 

 

 

 

 

 


System.ServiceModel

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<startup>

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

</startup>

<system.serviceModel>

<services>

<service behaviorConfiguration="NewBehavior0" name="WcfEmployee.EmployeeSrv">

<clear />

<endpoint address="basic" binding="basicHttpBinding" contract="WcfEmployee.IEmployeeSrv"

                    listenUriMode="Explicit">

<identity>

<certificateReference storeName="My" storeLocation="LocalMachine"

                            x509FindType="FindBySubjectName" findValue="OujianpingServer" />

</identity>

</endpoint>

<endpoint address="net.tcp://localhost:8082/Service" binding="netTcpBinding"

                    bindingConfiguration="NewBinding0" contract="WcfEmployee.IEmployeeSrv"

                    listenUriMode="Explicit">

<identity>

<certificateReference storeName="My" storeLocation="LocalMachine"

                            x509FindType="FindBySubjectName" findValue="OujianpingServer" />

</identity>

</endpoint>

<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""

                    contract="IMetadataExchange" />

<host>

<baseAddresses>

<add baseAddress="http://localhost/service" />

</baseAddresses>

</host>

</service>

</services>

<behaviors>

<serviceBehaviors>

<behavior name="NewBehavior0">

<serviceMetadata />

</behavior>

</serviceBehaviors>

</behaviors>

<bindings>

<netTcpBinding>

<binding name="NewBinding0">

<security>

<transport clientCredentialType="None" />

</security>

</binding>

</netTcpBinding>

</bindings>

</system.serviceModel>

</configuration>

 

注:今後可將以上文件當作一個模版來使用,比如新建了個了名爲wcflibwcf服務庫項目,在此項目中建立了一個名爲wcfserver的服務,並使用名爲myCert的證書,則可將文中的WcfEmployee替換爲wcflibEmployeeSrv替換爲wcfserverOujianpingServer替換爲myCert即可,而不必進行上述繁瑣的操作。

 

 

 

用以下命令創建證書

makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=OuJianpingServer -sky exchange -pe

(注:複製上述命令時須先整行顯示,且只能不能複製行尾的多餘空格,否則無法執行.

如下圖

 

安裝的證書可在控制檯(cmd mmc)的本地計算機證書下看到

(文件-添加/刪除管理單位-證書-計算機帳戶-本地計算機)

 

 

 

 

 

 

 

 

 

 

 


測試一下。
選按Ctrl+F5運行打開瀏覽器,

 

 

 

 

 

 

 

 

 

 

2.    Windows服務作爲宿主程序

建立Windows服務程序WinSrvEmployee

注意:必須選.Net Framework 4.5,與WCF服務庫項目保持一致,否則引入WCF服務庫會出現問題。
 


《圖2

第二步:WinSrvEmployee程序中添加兩個引用:一個是WCF服務庫Services項目的引用,另一個是System.ServiceModel引用。

 

第三步:修改Service1的屬性
Service1的設計界面中右擊,選擇屬性,把其中的(Name)ServiceName都改爲EmployeeSrv

 


《圖3

第四步:在Service1中編寫代碼如下

 

 

 


《圖4

ConsSrvHostEmployeev項目中的App.Config複製過來.爲防止元數據泄漏,應將其中以下內容刪除:

 

<endpointaddress="mex"binding="mexHttpBinding"bindingConfiguration=""

contract="IMetadataExchange" />

 


 

到這裏我們已經作好一個可以發佈EmployeeSrv服務的Windows Service宿主程序了。
下面我們要看一看如何把這個Windows Service運行起來。

第六步:爲服務添加安裝程序。
Service1設計界面中右擊,選擇添加安裝程序


《圖6
生成安裝程序組件,出現界面如下


《圖7
serviceProcessInstaller1:服務安裝的信息

 


《圖8
serviceInstaller1:服務本身的信息


《圖9
生成項目

安裝的服務

在計算機中搜索installutil.exe文件,找到版本最高的那個,將其路徑寫入環量變量path中。
打開VS2008命令窗口,進入當前項目的bin/Debug文件夾中,執行命令 installutil WinSrvEmployee.exe

(注:卸載時 InstallUtil.exe /u WinSrvEmployee.exe。)

啓動EmployeeSrv服務
打開服務管理器,我們可以看到我們剛剛註冊上的服務已經存在了,但還沒有啓動,右擊啓動


注意:上述通過windows server項目發佈在.net 3.5 vs 2008windows server 2003的環境下無法通過,表現爲啓動服務會出錯,會出現以下提示

,原因不明,但可以通過構建winform項目來代替,尤其是托盤型的winform應用。

 

 

二、 部署WCF服務器

 

 

 

三、 客戶端程序開發

(一)  創建WCF客戶端程序

(此步vs2008不必做)

 


using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.ServiceModel;

using System.ServiceModel.Description;

 

 

namespace EmployeeIMS

{

publicpartialclassForm1 : Form

    {

        ServiceReference1.EmployeeSrvClient mClient = new ServiceReference1.EmployeeSrvClient("NetTcpBinding_IEmployeeSrv");

public Form1()

        {

            InitializeComponent();

        }

 

privatevoid Form1_Load(object sender, EventArgs e)

        {

            mClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

            ServiceReference1.Employee employee = new ServiceReference1.Employee();

            employee.EmployeeName = "王芳";

            employee.EmployeeAge = 18;

            mClient.AddEmployees(employee);

            employee.EmployeeName = "李明";

            employee.EmployeeAge = 17;

            mClient.AddEmployees(employee);

 

string msg = "";

foreach(ServiceReference1.Employee em in mClient.GetAllEmployees())

            {

                msg += em.EmployeeName + "" + em.EmployeeAge + "\r";

            }

MessageBox.Show(msg);

 

        }

    }

}

 

 

(二)  修改app.config

Localhost

將app.config文件中的localhost替換爲WCF服務器的實際ip地址,否則在其他計算機上運行時無法連接到服務器。

SendTimeout

如果客戶端的請求需要服務花較長的時間才能回覆,且這個過程會超過1分鐘,則需要改變使用了進行數據傳輸的綁定(如netTcpBinding)的SendTimeout的值,並應該留有餘量,否則超過1分鐘後,客戶端將拋出超時的錯誤。

maxBufferPoolSize和maxBufferSize

如果傳輸的數據過大,則需要改變使用了進行數據傳輸的綁定(如netTcpBinding)的maxBufferPoolSize和maxBufferSize的值,否則,客戶端會拋出錯誤。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章