WCF は基本的に、クロスプロセス、クロスマシン、さらにはクロスネットワークのサービス呼び出しを提供します。この例では、ほとんどの関数はインターネット上の他の人の投稿から取得されています。巨人の肩の上で、O (∩_∩)O はは~、しかし、wcf についての理解を深めるために、デモを作成する際に遭遇した問題を示すために、同様のデモを作成することにしました。これは役立つと思います。 wcf を初めて使用するプログラマーも、さまざまな問題に遭遇するでしょう。さて、本題に入りましょう。
WCF は 4 つの部分に分かれています 1. コントラクト (インターフェイス) 2. サービス コントラクト (サービス) 3. WCF ホスト プログラム (コンソールまたは IIS) 4. クライアント (クライアント)
私は wcf を書くときに 4 つの部分を組み合わせるのが好きです部分は管理のために異なるクラス ライブラリに分割されます。
1. コントラクト
コントラクトは、クライアントに公開される関数名です。まず、図に示すように、Interface という名前の新しい wcf サービス ライブラリを作成します。プログラム内のデフォルト ファイル (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); } }
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; } }
<?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(); } } }
以下に示すように、コンソール プログラムを実行します。
2 番目: 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 } }
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 プロトコルが設定されます。次に、wcf プログラムを呼び出すためのクライアントを作成する必要があります。はい、
[Go] をクリックすると、次の図に示すように、システムが WCF サービスを見つけます。
[OK] をクリックすると、wcf が正常に参照されます。次に、WCF プログラムの呼び出しを開始します。たとえば、Add メソッドを呼び出します。コードは次のとおりです。デバッグ中はホスト プログラムとクライアント プログラムを同時に実行することを忘れないでください。
問題がある場合は、VS は複数のプロジェクトの同時開始をサポートしています。クライアントとホストを同時に開始できます。
以上がwcf の理解 -- 電卓機能の実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。