>백엔드 개발 >C#.Net 튜토리얼 >wcf의 이해 - 계산기 기능 구현

wcf의 이해 - 계산기 기능 구현

零下一度
零下一度원래의
2017-06-24 09:36:321881검색

WCF는 기본적으로 크로스 프로세스, 크로스 머신, 크로스 네트워크 서비스 호출을 제공합니다. 이 예에서는 주로 계산기의 기능을 구현합니다. 이는 대부분의 기능이 인터넷의 다른 사람의 게시물에서 가져온 것입니다. on the shoulder of 거인, O (∩_∩)O 하하~ 하지만 wcf에 대한 이해를 깊게 하기 위해 비슷한 데모를 작성하여 데모 작성 시 직면한 문제를 보여 주기로 결정했습니다. wcf를 처음 접하는 프로그래머라면 다양한 문제에 직면하게 될 것입니다. 좋아요, 요점을 살펴보겠습니다.

WCF는 네 부분으로 나누어집니다. 1. 계약(인터페이스) 2. 서비스 계약(서비스) 3. WCF 호스트 프로그램(콘솔 또는 IIS) 4. 클라이언트(클라이언트)

Wcf를 작성할 때 네 부분을 결합하는 것을 좋아합니다 각각 부분은 관리를 위해 여러 클래스 라이브러리로 분할됩니다.

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 Library"(새로운 계약을 생성하는 첫 번째 단계는 동일한 단계입니다), 클래스 라이브러리 이름은 Service,

생성 성공 후 삭제 기본 파일(App.config, IService1.cs, Service1.cs)을 추가하고 참조 "인터페이스" 클래스 라이브러리를 추가하고 새 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를 외부에 여는 방법 중 하나는 파일을 구성하고 모든 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        }
    }

호스트 프로그램의 기본 메서드를 다음과 같이 변경합니다.

    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 프로그램을 생성하고 "service reference"를 추가합니다

서비스 참조 추가(이것은 참조 방법은 "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는 프로그램이 실행되었습니다. 디버깅하는 동안 호스트 프로그램과 클라이언트 프로그램을 동시에 실행해야 합니다.

문제가 있는 경우 VS는 동시에 여러 프로젝트 시작을 지원합니다. 클라이언트와 호스트를 동시에 시작할 수 있습니다

위 내용은 wcf의 이해 - 계산기 기능 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.