wcf の理解 -- 電卓機能の実装

零下一度
零下一度オリジナル
2017-06-24 09:36:321879ブラウズ

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);

    }
}
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 ホスト プログラムを作成します。完成しましたが、外部プログラム呼び出し用のこれらのインターフェイスをホストするプログラムが必要です。そのため、これはホスト プログラムと呼ばれます。ホスト プログラムは、IIS 上に展開することも、デバッグを容易にするためにコンソール プログラムとして実行することもできます。以下では、これを使用して紹介します。コンソール プログラムをホスト プログラムとして使用します。ソリューションの名前を右クリックし、「コンソール プログラム」を Hosting という名前で追加し、インターフェイスとサービスへの参照を追加します。WCF を外部に開く方法は 2 つあります。1 つは、ファイルを構成してすべての 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();
            }
        }
    }

以下に示すように、コンソール プログラムを実行します。

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        }
    }

ホスト プログラムの 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 プロトコルが設定されます。次に、wcf プログラムを呼び出すためのクライアントを作成する必要があります。はい、

まず、ホスト プログラム Host をコンパイルし、bin/debug/Host.exe を見つけて、管理者を右クリックして開きます。次の図は、サービスがすでに Ning にあることを示しています

次に、ソリューション名を右クリックし、> Winform プログラムの追加 新しい WinForm プログラムを作成し、「サービス参照」を追加します

サービス参照を追加します (この参照このメソッドは、「3. ホスト プログラムの追加」 -> 「2 番目の WCF ヘルプ クラス メソッド」)に基づいています

[Go] をクリックすると、次の図に示すように、システムが WCF サービスを見つけます。

[OK] をクリックすると、wcf が正常に参照されます。次に、WCF プログラムの呼び出しを開始します。たとえば、Add メソッドを呼び出します。コードは次のとおりです。デバッグ中はホスト プログラムとクライアント プログラムを同時に実行することを忘れないでください。

問題がある場合は、VS は複数のプロジェクトの同時開始をサポートしています。クライアントとホストを同時に開始できます

以上がwcf の理解 -- 電卓機能の実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。