- WCF技術剖析(卷1)
- 蔣金楠
- 904字
- 2018-12-27 11:32:45
2.3.3 ListenUri和ListenUriMode
上面介紹了終結點的ListenUri屬性用于指定一個用于網絡監聽的物理地址,接下來討論與ListenUri相關的另一個主題:ListenUriMode。ListenUriMode代表的是確定真正監聽地址的模式。ListenUriMode通過System.ServiceModel.Description.ListenUriMode枚舉表示,而ListenUriMode定義了兩個枚舉值:Explicit和Unique。
public enum ListenUriMode { Explicit, Unique }
ListenUriMode.Explicit表示采用終結點ListenUri屬性設置的Uri作為最終的監聽地址;而Unique則根據ListenUri采用不同的策略保證最終使用的監聽地址是唯一的。而對于如何確保監聽地址的唯一性,WCF采用如下的策略:
● 如何采用TCP作為傳輸協議,在不采用端口共享的情況下,會選擇一個未被使用的端口作為最終監聽地址的端口以確保地址的唯一性;
● 如何采用TCP作為傳輸協議,同時在采用端口共享情況下,會添加一個GUID作為后綴以確保地址的唯一性;
● 對于非TCP作為傳輸協議,會添加一個GUID作為后綴以確保地址的唯一性。
在ServiceEndpoint中,定義了一個ListenUriMode屬性,用于指定終結點的ListenUriMode。
public class ServiceEndpoint { //其他成員 public Uri ListenUri { get; set; } public ListenUriMode ListenUriMode { get; set; } }
在對服務進行寄宿的時候,可以通過代碼的方式為添加的終結點指定ListenUriMode。下面的代碼將終結點設置成ListenUriMode.Unique。ListenUriMode也可以通過配置的方式進行指定,下面的配置和代碼是等效的。
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService))) { ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint (typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:9999/CalculatorService", new Uri("http://127.0.0.1:8888/CalculatorService")); endpoint.ListenUriMode = ListenUriMode.Unique; Console.Read(); } <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Artech.ListenUriDemos.Services.CalculatorService"> <endpoint address="http://127.0.0.1:9999/CalculatorService" binding="wsHttpBinding" contract="Artech.ListenUriDemos. Contracts.ICalculator" listenUriMode="Unique" listenUri="http://127.0.0.1:8888/CalculatorService" /> </service> </services> </system.serviceModel> </configuration>
案例演示:驗證監聽地址唯一性
為了驗證ListenUriMode.Unique模式下確保監聽地址的唯一性,我寫了一個簡單的例子。在對服務(Artech.ListenUriDemos.Services.CalculatorService)進行寄宿的時候,為之添加了5個終結點,具體的配置如表2-1所示:
表2-1

<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding name="PortSharingBinding" portSharingEnabled="true"/> </netTcpBinding> </bindings> <services> <service name="Artech.ListenUriDemos.Services. CalculatorService"> <!--1. BasicHttpBinding & ListenUriMode.Explicit--> <endpoint address="http://127.0.0.1:5555/service1" binding="basicHttpBinding" name="httpExplicitListenUriMode" contract= "Artech.ListenUriDemos.Contracts.ICalculator" /> <!--2. BasicHttpBinding & ListenUriMode.Unique--> <endpoint address="http://127.0.0.1:6666/service2" binding= "basicHttpBinding" name="httpUniquListenUriMode" contract="Artech. ListenUriDemos.Contracts.ICalculator" listenUriMode="Unique" /> <!--3. NetTcpBinding & ListenUriMode.Explicit--> <endpoint address="net.tcp://127.0.0.1:7777/service3" binding="netTcpBinding" bindingConfiguration="" name="tcpExplicitListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculator"/> <!--4. NetTcpBinding & ListenUriMode.Unique--> <endpoint address="net.tcp://127.0.0.1:8888/service4" binding="netTcpBinding" bindingConfiguration="" name="tcpUniquListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculator" listenUriMode="Unique" /> <!--5. NetTcpBinding & ListenUriMode.Unique & Port Sharing--> <endpoint address="net.tcp://127.0.0.1:9999/service5" binding="netTcpBinding" bindingConfiguration="PortSharingBinding" name= "tcpPortSharingUniquListenUriMode" contract="Artech.ListenUriDemos.Contracts.ICalculator" listenUriMode="Unique" /> </service> </services> </system.serviceModel> </configuration>
在一個控制臺應用程序中,通過下面的代碼實現對服務的寄宿。當ServiceHost對象成功開啟時,遍歷ServiceHost的ChannelDispatcher列表,并將ChannelDispatcher對象的ChannelListener的URI打印出來。
using System; using System.ServiceModel; using Artech.ListenUriDemos.Services; using System.ServiceModel.Dispatcher; namespace Artech.ListenUriDemos.Hosting {
class Program
{ static void Main(string[] args) { using (ServiceHost serviceHost = new ServiceHost (typeof(CalculatorService))) { serviceHost.Open(); int i = 0; foreach (ChannelDispatcher channelDispatcher in serviceHost. ChannelDispatchers) { Console.WriteLine("第{0}個終結點的監聽地址為: {1}", ++i, channelDispatcher.Listener.Uri); } Console.Read(); } } } }
最終的輸出如下,從中可以看出,對于ListenUriMode.Unique的3個終結點(第2個、第4個和第5個),第2個終結點采用了基于HTTP的BasicHttpBinding,WCF通過加一個GUID后綴確保監聽地址的唯一性;基于NetTcpBinding的第4個終結點,通過使用一個可用的端口(1119)確保監聽地址的唯一性;而對于采用了NetTcpBinding的第5個終結點,由于開啟了端口共享,不能改變其端口,所以仍然采用添加GUID后綴的方式確保監聽地址的唯一性。
第1個終結點的監聽地址為: http://127.0.0.1:5555/service1 第2個終結點的監聽地址為: http://127.0.0.1:6666/service2/d9ce6f30-3103-4ec9- b73b-34f32c65b0a1 第3個終結點的監聽地址為: net.tcp://127.0.0.1:7777/service3 第4個終結點的監聽地址為: net.tcp://127.0.0.1:1119/service4 第5個終結點的監聽地址為: net.tcp://127.0.0.1:9999/service5/b4f69288-913b- 43ec-8e42-e58f150ee91c
- Getting Started with Citrix XenApp? 7.6
- Unreal Engine Physics Essentials
- 在最好的年紀學Python:小學生趣味編程
- Objective-C Memory Management Essentials
- Mastering SVG
- Learning RabbitMQ
- DevOps入門與實踐
- 羅克韋爾ControlLogix系統應用技術
- Python金融數據分析
- ASP.NET 3.5程序設計與項目實踐
- Swift語言實戰精講
- Visual Basic程序設計實驗指導(第二版)
- Android開發三劍客:UML、模式與測試
- Java程序設計實用教程(第2版)
- Python Linux系統管理與自動化運維