對wcf的理解--實現計算機功能

來源:互聯網
上載者:User
WCF本質上提供一個跨進程、跨機器以致跨網路的服務調用 ,本樣本中 主要實現了計算機的功能,大部分的函數來源於網上別人的文章,這叫站在巨人的肩膀上,O(∩_∩)O哈哈~,但是為了加深自己的對wcf的理解,因此決定自己在寫個類似的demo,把寫demo中遇到的問題展現出來,我相信對於初識wcf的程式員了來說,也會遇到各種問題。好了步入正題。

WCF 分為四個部分 1、契約(Interface)2、服務契約(Service)3、WCF 宿主程式(控制台或者IIS) 4、用戶端(Client)

本人在寫wcf的時候喜歡將四個部分分別拆分成不同的類庫來管理。

1、契約

契約是對外開放的介面,暴露給用戶端的函數名稱首先,建立一個wcf服務庫,名稱為Interface,:

刪掉程式中預設的檔案(App.config,IService1.cs,Service1.cs),建立ICalculator

namespace Interface{    [ServiceContract(Name = "CalculatorService", Namespace = "")]public interface ICalculator    {        [OperationContract]double Add(double x, double y);        [OperationContract]double Subtract(double x, double y);        [OperationContract]double Multiply(double x, double y);        [OperationContract]double Divide(double x, double y);    }}

2、建立服務契約,其實就是實現契約的類 ,添加"建立項目"->WCF->"WCF服務庫" (如 第一步建立契約是一樣的步驟),類庫的名稱為Service,

建立成功後,刪除預設檔案(App.config,IService1.cs,Service1.cs),添加引用"Interface" 類庫,建立CalculatorService 並實現ICalculator

namespace Service{    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]public class CalculatorService : ICalculator    {public double Add(double x, double y)        {return x + y;        }public double Subtract(double x, double y)        {return x - y;        }public double Multiply(double x, double y)        {return x * y;        }public double Divide(double x, double y)        {return x / y;        }    }

3、建立WCF宿主程式,WCF的契約和服務契約都已經建完,但是還需要一個程式來承載這些介面供外部程式調用,因此稱之為宿主程式,宿主程式可以部署在IIS上,也可以用控制台程式運行方便調試,下面我就介紹用控制台程式作為宿主程式。在解決方案的名稱右鍵添加"控制台程式" 名稱為Hosting ,添加對Interface和Service的引用

實現wcf對外開放有兩種方式,一種方式是設定檔,將所有的WCF資訊都寫到設定檔中

第一種:WCF的相關資訊寫到設定檔(App.config)中

<?xml version="1.0" encoding="utf-8"?><configuration>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>  </startup>  <system.serviceModel>    <services>      <service name="Service.CalculatorService" behaviorConfiguration="WCFService.WCFServiceBehavior">        <endpoint address="http://127.0.0.1:8888/CalculatorService" binding="wsHttpBinding" contract="Service.Interface.ICalculator">                  </endpoint>        <endpoint address="net.tcp://127.0.0.1:9999/CalculatorService"  binding="netTcpBinding"  contract="Service.Interface.ICalculator">        </endpoint>        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />        <host>          <baseAddresses>            <add baseAddress="http://127.0.0.1:8888/"/>            <add baseAddress="net.tcp://127.0.0.1:9999/"/>          </baseAddresses>        </host>      </service>    </services>    <behaviors>      <serviceBehaviors>        <behavior name="WCFService.WCFServiceBehavior">          <serviceMetadata httpGetEnabled="true" />          <serviceDebug includeExceptionDetailInFaults="false" />        </behavior>      </serviceBehaviors>    </behaviors>  </system.serviceModel></configuration>

Main方法的主要代碼如下,

    public class Program    {internal static ServiceHost host = null;static void Main(string[] args)        {using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))            {                host.Opened += delegate{                    Console.WriteLine("CalculaorService已經啟動,按任意鍵終止服務!");                };                host.Open();                Console.ReadLine();            }        }    }

運行控制台程式,如所示:

第二種:寫一個WCFHelper類,添加協助類的時候,一定引用System.Runtime.Serialization ,並且刪掉App.config 對wcf的配置,否則會報錯代碼如下:

 public static class WCFHelper    {public static string IP { get; set; }public static int Port { get; set; }static WCFHelper()        {try{                IP = System.Environment.MachineName;// ConfigurationManager.AppSettings["ServiceIP"];//                Port = int.Parse(ConfigurationManager.AppSettings["ServicePort"]);            }catch{            }            EndpointAddress.Add(BindingProtocol.Http, "http://{0}:{1}/{2}/{3}");            EndpointAddress.Add(BindingProtocol.NetTcp, "net.tcp://{0}:{1}/{2}/{3}");//EndpointAddress.Add(BindingProtocol.NetMsmq, "net.msmq://{0}:{1}/" + schema + "/{2}");//EndpointAddress.Add(BindingProtocol.NetPipe, "net.pipe://{0}:{1}/" + schema + "/{2}");try{                httpBinding = new BasicHttpBinding();                httpBinding.MaxBufferSize = 200065536;                httpBinding.MaxReceivedMessageSize = 200065536;                httpBinding.CloseTimeout = new TimeSpan(0, 10, 0);                httpBinding.OpenTimeout = new TimeSpan(0, 10, 0);                httpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);                httpBinding.SendTimeout = new TimeSpan(0, 1, 0);                httpBinding.Security.Mode = BasicHttpSecurityMode.None;                httpBinding.ReaderQuotas.MaxDepth = 64;                httpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;                httpBinding.ReaderQuotas.MaxArrayLength = 16384;                httpBinding.ReaderQuotas.MaxBytesPerRead = 4096;                httpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;            }catch{                httpBinding = new BasicHttpBinding();            }try{                tcpBinding = new NetTcpBinding();                tcpBinding.CloseTimeout = new TimeSpan(0, 1, 0);                tcpBinding.OpenTimeout = new TimeSpan(0, 1, 0);                tcpBinding.ReceiveTimeout = new TimeSpan(0, 10, 0);                tcpBinding.SendTimeout = new TimeSpan(0, 1, 0);                tcpBinding.TransactionFlow = false;                tcpBinding.TransferMode = TransferMode.Buffered;                tcpBinding.TransactionProtocol = TransactionProtocol.OleTransactions;                tcpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;                tcpBinding.ListenBacklog = 100000;                tcpBinding.MaxBufferPoolSize = 524288;                tcpBinding.MaxBufferSize = 200065536;                tcpBinding.MaxConnections = 2000;                tcpBinding.MaxReceivedMessageSize = 200065536;                tcpBinding.PortSharingEnabled = true;                tcpBinding.Security.Mode = SecurityMode.None;                tcpBinding.ReaderQuotas.MaxDepth = 64;                tcpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;                tcpBinding.ReaderQuotas.MaxArrayLength = 163840000;                tcpBinding.ReaderQuotas.MaxBytesPerRead = 4096;                tcpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;                tcpBinding.ReliableSession.Ordered = true;                tcpBinding.ReliableSession.InactivityTimeout = new TimeSpan(0, 10, 0);                tcpBinding.ReliableSession.Enabled = false;            }catch{                tcpBinding = new NetTcpBinding();            }        }private static BasicHttpBinding httpBinding;public static BasicHttpBinding HttpBinding        {get{return httpBinding;            }        }private static NetTcpBinding tcpBinding;public static NetTcpBinding TcpBinding        {get{return tcpBinding;            }        }public static EndpointAddress GetEndpointAddress(string ip, int port, string serviceSchema, string serviceName, BindingProtocol protocol)        {string address = EndpointAddress[protocol];            address = string.Format(address, ip, port, serviceSchema, serviceName);return new EndpointAddress(address);        }public static EndpointAddress GetEndpointAddress(string serviceSchema, string serviceName, BindingProtocol protocol)        {string address = EndpointAddress[protocol];            address = string.Format(address, IP, Port, serviceSchema, serviceName);return new EndpointAddress(address);        }public static Uri GetBaseAddress(string ip, int port, string serviceSchema, string serviceName, BindingProtocol protocol)        {string address = EndpointAddress[protocol];            address = string.Format(address, ip, port + 1, serviceSchema, serviceName);return new Uri(address);        }public static Uri GetBaseAddress(string serviceSchema, string serviceName, BindingProtocol protocol)        {string address = EndpointAddress[protocol];            address = string.Format(address, IP, Port + 1, serviceSchema, serviceName);return new Uri(address);        }private readonly static Dictionary<BindingProtocol, string> EndpointAddress = new Dictionary<BindingProtocol, string>();public enum BindingProtocol        {            Http = 1,            NetTcp = 2,//NetPipe = 3,//NetMsmq = 4        }    }

將 宿主程式中的main方法改成如下:

    static void Main(string[] args)        {            WCFHelper.IP = "127.0.0.10";            WCFHelper.Port = 9999;            Uri httpUri = WCFHelper.GetBaseAddress(WCFHelper.IP, WCFHelper.Port, "Calculator", "Inspect", WCFHelper.BindingProtocol.Http);using (ServiceHost host = new ServiceHost(typeof(CalculatorService), httpUri))            {                host.AddServiceEndpoint(typeof(ICalculator), WCFHelper.TcpBinding, WCFHelper.GetEndpointAddress(WCFHelper.IP, WCFHelper.Port, "Calculator", "InspectService", WCFHelper.BindingProtocol.NetTcp).Uri.AbsoluteUri);                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();#if DEBUGbehavior.HttpGetEnabled = true;#elsebehavior.HttpGetEnabled = false;#endifhost.Description.Behaviors.Add(behavior);                host.Opened += delegate{                    Console.WriteLine("CalculaorService已經啟動,按任意鍵終止服務!");                };                host.Open();                Console.ReadLine();            }}

4、宿主程式建完了,WCF的所有鍥約已經對外可以訪問了,那現在需要建立Client 去調用wcf程式了 ,

首先,編譯宿主程式Host,找到bin/debug/ Host.exe 右鍵管理員開啟,如果如證明服務已經於寧

其次,在解決方案名稱->右鍵添加Winform程式 建立WinForm 程式,添加"服務引用"

加入服務參考 (此引用方式,是以"3、添加宿主程式" ->"第二種 WCF協助類的方式")

點擊“轉到” 系統發現WCF服務,如所示:

點擊確定,就成功的將wcf的引用了,下面開始調用WCF的程式了,例如調用Add方法,代碼如下:

 ServiceReference1.CalculatorServiceClient client = new ServiceReference1.CalculatorServiceClient();            textBox3.Text = client.Add(double.Parse(textBox1.Text), double.Parse(textBox2.Text)).ToString();

到此為止,wcf程式已經完成的跑通了,記得 調試的時候已經把宿主程式和client程式同時運行。

如果閑麻煩,vs 支援同時啟動多重專案,可以同時把client 和host同時啟動

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.