WCF 學習總結2 -- 配置WCF
前面一篇文章《WCF 學習總結1 -- 簡單例項》一股腦兒展示了幾種WCF部署方式,其中配置檔案(App.config/Web.config)都是IDE自動生成,省去了我們不少功夫。現在回過頭來看看IDE提供的Wcf Service Library專案模板中的預設服務端配置檔案——App.config裡面究竟有什麼祕密。
服務端的配置檔案主要是對services、bindings、behaviors的配置。在預設的App.config中,使用的是WCF Framework定義好的wsHttpBinding預設配置,所以看不到binding配置節。
配置節展開如下圖:
BTW: "元資料端點”通過WS-MetadataExchange幫我們實現了對服務的描述,提供了WSDL,啟動Host之後我們可以通過
配置節展開如下圖:
關於WCF中的地址和繫結,需要補充一下。
WCF中支援的傳輸協議包括HTTP、TCP、Peer network(對等網)、IPC(基於命名管道的內部程序通訊)以及MSMQ(微軟訊息佇列),每個協議對應一個地址型別:
- HTTP地址:http://localhost:8080/
- TCP地址: net.tcp://localhost:8080/
- IPC地址: net.pipe://localhost/ (適用於跨程序,不能使用於不同機器間)
- MSMQ地址: net.msmq://localhost/
- 對等網地址: net.p2p://localhost/
WCF中提供的繫結有:
- BasicHttpBinding: 最簡單的繫結型別,通常用於 Web Services。使用 HTTP 協議,Text/XML 編碼方式。
- WSHttpBinding: 比 BasicHttpBinding 更加安全,通常用於 non-duplex 服務通訊。
- WSDualHttpBinding: 和 WSHttpBinding 相比,它支援 duplex 型別的服務。
- WSFederationHttpBinding: 支援 WS-Federation 安全通訊協議。
- NetTcpBinding: 效率最高,安全的跨機器通訊方式。
- NetNamedPipeBinding: 安全、可靠、高效的單機服務通訊方式。
- NetMsmqBinding: 使用訊息佇列在不同機器間進行通訊。
- NetPeerTcpBinding: 使用 P2P 協議在多機器間通訊。
- MsmqIntegrationBinding: 使用現有的訊息佇列系統進行跨機器通訊。如 MSMQ。 ------ 弱弱的分隔線 -----
OK,有了上面的基礎,就讓WCF風暴來的猛烈些吧。做一個多服務,多端點的示例。
1.WcfServiceLib 程式碼:
[ServiceContract]
public interface IService
{
[OperationContract]
string GetMessage();
}
public class Service1 : IService
{
public string GetMessage()
{
var address = OperationContext.Current.Channel.LocalAddress.ToString();
return string.Format("From Server1: Hello Client at [{0}]", address);
}
}
public class Service2 : IService
{
public string GetMessage()
{
var address = OperationContext.Current.Channel.LocalAddress.ToString();
return string.Format("來自 Service2: 好 Client at [{0}]", address);
}
}
2.WcfConsoleHost 程式碼:
static void Main(string[] args)
{
ServiceHost host1 = new ServiceHost(typeof(WcfServiceLib.Service1));
host1.Open();
Console.WriteLine("Server1 Opened!");
ServiceHost host2 = new ServiceHost(typeof(WcfServiceLib.Service2));
host2.Open();
Console.WriteLine("Server2 Opened!");
Console.Read();
}
3.服務端配置檔案:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfServiceLib.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:9999/WcfStudy3/Service1" />
<add baseAddress = "net.tcp://localhost:8888/WcfStudy3/Service1" />
</baseAddresses>
</host>
<endpoint address ="serviceEN_1" binding="wsHttpBinding" contract="WcfServiceLib.IService" />
<endpoint address ="serviceEN_2" binding="mexTcpBinding" contract="WcfServiceLib.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<service name="WcfServiceLib.Service2">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:9999/WcfStudy3/Service2" />
<add baseAddress = "net.tcp://localhost:8888/WcfStudy3/Service2" />
</baseAddresses>
</host>
<endpoint address ="serviceCH_1" binding="wsHttpBinding" contract="WcfServiceLib.IService" />
<endpoint address ="serviceCH_2" binding="mexTcpBinding" contract="WcfServiceLib.IService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
4. 啟動Host,在Client工程中新增Service Reference 因為有兩個Service,所以要新增兩次。 (1) WcfSvc1(Url:http://localhost:9999/WcfStudy3/Service1)
(2) WcfSvc2(Url:http://localhost:9999/WcfStudy3/Service2) 圖略
5. 客戶端配置檔案: 配置節中,生成了4個Endpoint,分別對應服務端的4個Endpoint。通過 name屬性區別。
<client>
<endpoint address="http://localhost:9999/WcfStudy3/Service1/serviceEN_1"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="WcfSvc1.IService" name="WSHttpBinding_IService">
</endpoint>
<endpoint address="net.tcp://localhost:8888/WcfStudy3/Service1/serviceEN_2"
binding="netTcpBinding" bindingConfiguration="MetadataExchangeTcpBinding_IService"
contract="WcfSvc1.IService" name="MetadataExchangeTcpBinding_IService" />
<endpoint address="http://localhost:9999/WcfStudy3/Service2/serviceCH_1"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="WcfSvc2.IService" name="WSHttpBinding_IService1">
</endpoint>
<endpoint address="net.tcp://localhost:8888/WcfStudy3/Service2/serviceCH_2"
binding="netTcpBinding" bindingConfiguration="MetadataExchangeTcpBinding_IService1"
contract="WcfSvc2.IService" name="MetadataExchangeTcpBinding_IService1" />
</client>
6. 客戶端程式碼:
static void Main(string[] args)
{
Console.WriteLine("------------");
WcfSvc1.ServiceClient client1_1 = new WcfSvc1.ServiceClient("WSHttpBinding_IService");
Console.WriteLine(client1_1.GetMessage());
Console.WriteLine("------------");
WcfSvc1.ServiceClient client1_2 = new WcfSvc1.ServiceClient("MetadataExchangeTcpBinding_IService");
Console.WriteLine(client1_2.GetMessage());
Console.WriteLine("------------");
WcfSvc2.ServiceClient client2_1 = new WcfSvc2.ServiceClient("WSHttpBinding_IService1");
Console.WriteLine(client2_1.GetMessage());
Console.WriteLine("------------");
WcfSvc2.ServiceClient client2_2 = new WcfSvc2.ServiceClient("MetadataExchangeTcpBinding_IService1");
Console.WriteLine(client2_2.GetMessage());
Console.Read();
}
7.執行結果: