집 >백엔드 개발 >C#.Net 튜토리얼 >wcf의 이해 - 계산기 기능 구현
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(); } } }아래 표시된 대로 콘솔 프로그램을 실행합니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!