- WCF技術(shù)剖析(卷1)
- 蔣金楠
- 1366字
- 2018-12-27 11:32:35
1.3.5 步驟五 創(chuàng)建客戶端調(diào)用服務(wù)
服務(wù)被成功寄宿后,服務(wù)端便開始了服務(wù)調(diào)用請求的監(jiān)聽工作。此外,服務(wù)寄宿將服務(wù)描述通過元數(shù)據(jù)的形式發(fā)布出來,相應(yīng)的客戶端就可以獲取這些元數(shù)據(jù),創(chuàng)建客戶端程序進(jìn)行服務(wù)的消費(fèi)。在VS下,當(dāng)我們添加服務(wù)引用的時候,VS在內(nèi)部幫我們實(shí)現(xiàn)元數(shù)據(jù)的獲取,并借助這些元數(shù)據(jù)通過代碼生成工具(SvcUtil.exe)自動生成用于服務(wù)調(diào)用的服務(wù)代理相關(guān)代碼和相應(yīng)的配置。
在運(yùn)行服務(wù)寄宿程序(Hosting.exe)的情況下,右鍵點(diǎn)擊Client項(xiàng)目,在彈出的上下文菜單中選擇“添加服務(wù)引用(Add Service References)”,如圖1-7所示的添加服務(wù)引用的對話會顯示出來。在地址欄上鍵入服務(wù)元數(shù)據(jù)發(fā)布的源地址:http://127.0.0.1:9999/calculatorservice/metadata,并指定一個命名空間,點(diǎn)擊OK按鈕,VS為你生成一系列用于服務(wù)調(diào)用的代碼和配置。

圖1-7 添加服務(wù)引用
在一系列自動生成的類中,包含一個服務(wù)契約接口、一個服務(wù)代理對象和其他相關(guān)的類。被客戶端直接用于服務(wù)調(diào)用的是一個繼承自ClientBase<CalculatorService>并實(shí)現(xiàn)了CalculatorService接口(CalculatorService為客戶端生成的服務(wù)契約接口類型)的服務(wù)代理類。ClientBase<CalculatorService>的定義如下所示:
namespace Artech.WcfServices.Client.CalculatorServices { //其他類型成員 [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class CalculatorServiceClient : System.ServiceModel. ClientBase<Artech.WcfServices.Client.CalculatorServices. CalculatorService>, Artech.WcfServices.Client.CalculatorServices. CalculatorService { public CalculatorServiceClient() { } public CalculatorServiceClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CalculatorServiceClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public double Add(double x, double y) { return base.Channel.Add(x, y); } public double Subtract(double x, double y) { return base.Channel.Subtract(x, y); } public double Multiply(double x, double y) { return base.Channel.Multiply(x, y); } public double Divide(double x, double y) { return base.Channel.Divide(x, y); } }
我們可以創(chuàng)建CalculatorServiceClient對象,執(zhí)行相應(yīng)方法調(diào)用服務(wù)操作。客戶端進(jìn)行服務(wù)調(diào)用的代碼如下:
using System; using Artech.WcfServices.Client.CalculatorServices; namespace Artech.WcfServices.Client { class Program { static void Main(string[] args) { using (CalculatorServiceClient proxy = new CalculatorServiceClient()) { Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2)); Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2)); Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2)); Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2)); } } } }
運(yùn)行后輸出:
x + y = 3 when x = 1 and y = 2 x - y = -1 when x = 1 and y = 2 x * y = 2 when x = 1 and y = 2 x / y = 0.5 when x = 1 and y = 2
客戶端通過服務(wù)代理對象進(jìn)行服務(wù)的調(diào)用,上面的例子通過創(chuàng)建自動生成的、繼承自ClientBase<T>的類型對象進(jìn)行服務(wù)調(diào)用。實(shí)際上,我們還有另外一種創(chuàng)建服務(wù)代理的方法,就是通過ChannelFactory<T>。此外,WCF采用基于契約的服務(wù)調(diào)用方法,從上面的例子我們也可以看到,VS在進(jìn)行服務(wù)引用添加的過程中,會在客戶端創(chuàng)建一個與服務(wù)端等效的服務(wù)契約接口。在上面的例子中,由于服務(wù)端和客戶端都在同一個解決方案中,完全可以讓服務(wù)端和客戶端引用相同的契約。
為了演示這種場景,我們將添加的服務(wù)引用移除,并為Client項(xiàng)目添加對Contracts項(xiàng)目的引用。借助于這個服務(wù)契約,并通過ChannelFactory<ICalculator>創(chuàng)建服務(wù)代理對象,直接進(jìn)行相應(yīng)的服務(wù)調(diào)用。下面的代碼演示了基于ChannelFacotory<T>進(jìn)行服務(wù)代理的創(chuàng)建和服務(wù)調(diào)用的方式。
using System; using System.ServiceModel; using Artech.WcfServices.Contracts; namespace Artech.WcfServices.Client { class Program { static void Main(string[] args) { using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice")) { ICalculator proxy = channelFactory.CreateChannel(); using (proxy as IDisposable) { Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2)); Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2)); Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2)); Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2)); } } } } }
由于終結(jié)點(diǎn)是WCF進(jìn)行通信的唯一手段,ChannelFactory<T>本質(zhì)上是通過指定的終結(jié)點(diǎn)創(chuàng)建用于進(jìn)行服務(wù)調(diào)用的服務(wù)代理。在上面的代碼中,在創(chuàng)建ChannelFactory<T>的時候再在構(gòu)造函數(shù)中指定終結(jié)點(diǎn)的相關(guān)要素(契約通過泛型類型表示,地址和綁定則通過參數(shù)指定)。在真正的WCF應(yīng)用中,大都采用配置的方式進(jìn)行終結(jié)點(diǎn)的定義。我們可以通過下面的配置指定終結(jié)點(diǎn)的三要素,并為相應(yīng)的終結(jié)點(diǎn)指定一個終結(jié)點(diǎn)配置名稱(calculatorservice)。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts. ICalculator" name="calculatorservice" /> </client> </system.serviceModel> </configuration>
那么在創(chuàng)建ChannelFactory<T>的時候,就無須再指定終結(jié)點(diǎn)的綁定和地址了,只須制定對應(yīng)的終結(jié)點(diǎn)配置名稱。
using System; using System.ServiceModel; using Artech.WcfServices.Contracts; namespace Artech.WcfServices.Client { class Program { static void Main(string[] args) { using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>( "calculatorservice")) { //省略代碼 } } } }
- iOS面試一戰(zhàn)到底
- Learn Blockchain Programming with JavaScript
- 移動UI設(shè)計(jì)(微課版)
- Learn to Create WordPress Themes by Building 5 Projects
- AWS Serverless架構(gòu):使用AWS從傳統(tǒng)部署方式向Serverless架構(gòu)遷移
- Machine Learning with R Cookbook(Second Edition)
- VSTO開發(fā)入門教程
- 嚴(yán)密系統(tǒng)設(shè)計(jì):方法、趨勢與挑戰(zhàn)
- Rust Essentials(Second Edition)
- 程序設(shè)計(jì)基礎(chǔ)教程:C語言
- C語言程序設(shè)計(jì)
- Instant PHP Web Scraping
- JavaScript應(yīng)用開發(fā)實(shí)踐指南
- Developing SSRS Reports for Dynamics AX
- 零基礎(chǔ)學(xué)C語言(升級版)