WCF 클라이언트 개요

이 섹션에서는 클라이언트 애플리케이션이 수행하는 작업, WCF(Windows Communication Foundation) 클라이언트를 구성, 생성, 사용하는 방법, 클라이언트 애플리케이션의 보안을 유지하는 방법을 설명합니다.

WCF 클라이언트 개체 사용

클라이언트 애플리케이션은 WCF 클라이언트를 사용하여 다른 애플리케이션과 통신하는, 관리되는 애플리케이션입니다. WCF 서비스에 대한 클라이언트 애플리케이션을 만들려면 다음 단계를 수행해야 합니다.

  1. 서비스 엔드포인트에 대한 서비스 계약, 바인딩 및 주소 정보를 가져옵니다.

  2. 해당 정보를 사용하여 WCF 클라이언트를 만듭니다.

  3. 작업을 호출합니다.

  4. WCF 클라이언트 개체를 닫습니다.

다음 단원에서는 이러한 단계에 대해 설명하고 다음과 같은 문제를 간략하게 소개합니다.

  • 오류 처리.

  • 클라이언트 구성 및 보안

  • 이중 서비스에 대한 콜백 개체 만들기

  • 비동기적으로 서비스 호출

  • 클라이언트 채널을 사용하여 서비스 호출

서비스 계약, 바인딩 및 주소 가져오기

WCF에서 서비스 및 클라이언트는 관리되는 특성, 인터페이스, 메서드를 사용하여 계약을 모델링합니다. 클라이언트 애플리케이션에서 서비스에 연결하려면 서비스 계약에 대한 형식 정보를 가져와야 합니다. 일반적으로 ServiceModel 메타데이터 유틸리티 도구(Svcutil.exe)를 사용하여 서비스 계약 형식 정보를 가져옵니다. 유틸리티는 서비스에서 메타데이터를 다운로드한 다음, 선택한 언어를 사용하여 관리되는 소스 코드 파일로 변환합니다. 그런 다음, WCF 클라이언트 개체를 구성하는 데 사용할 수 있는 클라이언트 애플리케이션 구성 파일을 만듭니다. 예를 들어, WCF 클라이언트 개체를 만들어 MyCalculatorService를 호출하려는 경우에 해당 서비스에 대한 메타데이터가 http://computerName/MyCalculatorService/Service.svc?wsdl에 게시된다면, 다음 코드 예제에서는 Svcutil.exe를 사용하여 관리되는 코드에 서비스 계약이 들어 있는 ClientCode.vb 파일을 가져오는 방법을 보여 줍니다.

svcutil /language:vb /out:ClientCode.vb /config:app.config http://computerName/MyCalculatorService/Service.svc?wsdl  

클라이언트 애플리케이션에서 WCF 클라이언트 개체를 만드는 데 사용할 수 있는 다른 어셈블리나 클라이언트 애플리케이션으로 이 계약 코드를 컴파일할 수 있습니다. 구성 파일을 사용하여 클라이언트 개체가 서비스에 제대로 연결하도록 구성할 수 있습니다.

이 프로세스의 예제는 방법: 클라이언트 만들기를 참조하세요. 계약에 대한 자세한 내용은 계약을 참조하세요.

WCF 클라이언트 개체 만들기

WCF 클라이언트는 클라이언트가 원격 서비스와 통신하는 데 사용할 수 있는 형식으로 WCF 서비스를 나타내는 로컬 개체입니다. WCF 클라이언트 형식은 대상 서비스 계약을 구현하기 때문에 대상 서비스 계약을 만들어 구성할 경우 클라이언트 개체를 사용하여 서비스 작업을 직접 호출할 수 있습니다. WCF 런타임은 메서드 호출을 메시지로 변환하여 서비스로 보내고, 회신을 수신한 다음 해당 값을 WCF 클라이언트 개체에 반환하거나 out 또는 ref 매개 변수로 반환합니다.

WCF 클라이언트 채널 개체를 사용하여 서비스를 연결한 후 사용할 수도 있습니다. 자세한 내용은 WCF 클라이언트 아키텍처를 참조하세요.

새 WCF 개체 만들기

ClientBase<TChannel> 클래스 사용을 설명하기 위해 다음 서비스 계약이 생성되어 있는 것으로 가정합니다.

참고 항목

Visual Studio 를 사용하여 WCF 클라이언트를 만들 경우 프로젝트에 대한 서비스 참조를 추가하면 개체가 개체 브라우저에 자동으로 로드됩니다.

[System.ServiceModel.ServiceContractAttribute(
  Namespace = "http://microsoft.wcf.documentation"
)]
public interface ISampleService
{
    [System.ServiceModel.OperationContractAttribute(
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethod",
      ReplyAction = "http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse"
    )]
    [System.ServiceModel.FaultContractAttribute(
      typeof(microsoft.wcf.documentation.SampleFault),
      Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault"
    )]
    string SampleMethod(string msg);
}

Visual Studio를 사용하지 않는 경우 생성된 계약 코드를 조사하여 ClientBase<TChannel> 및 서비스 계약 인터페이스 ISampleService를 확장하는 형식을 찾습니다. 이 경우 형식은 다음 코드와 비슷합니다.

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{

    public SampleServiceClient()
    {
    }

    public SampleServiceClient(string endpointConfigurationName)
        :
            base(endpointConfigurationName)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, string remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public SampleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
        :
            base(binding, remoteAddress)
    {
    }
    public string SampleMethod(string msg)
    {
        return base.Channel.SampleMethod(msg);
    }
}

생성자 중 하나를 사용하여 이 클래스를 로컬 개체로 만든 다음 구성하여 ISampleService 형식 서비스에 연결하는 데 사용할 수 있습니다.

WCF 클라이언트 개체를 먼저 만든 다음 단일 try/catch 블록에서 해당 개체를 사용하고 닫는 것이 좋습니다. 특정 실패 모드에서 예외를 마스킹할 수 있으므로 using 문(Visual Basic의 Using)을 사용하지 마세요. 자세한 내용은 다음 섹션 및 닫기 및 중단을 사용하여 WCF 클라이언트 리소스 해제를 참조하세요.

계약, 바인딩 및 주소

WCF 클라이언트 개체를 만들려면 클라이언트 개체를 구성해야 합니다. 특히 클라이언트 개체에는 사용할 서비스 엔드포인트가 있어야 합니다. 엔드포인트는 서비스 계약, 바인딩 및 주소의 조합입니다. (엔드포인트에 대한 자세한 내용은 엔드포인트: 주소, 바인딩, 계약 참조) 일반적으로 이 정보는 클라이언트 애플리케이션 구성 파일의 <endpoint> 요소(예: Svcutil.exe 도구에서 생성되는 요소)에 있으며 클라이언트 개체를 만들 때 자동으로 로드됩니다. 두 WCF 클라이언트 형식에는 이 정보를 프로그래밍 방식으로 지정할 수 있게 해주는 오버로드가 있습니다.

예를 들어, 이전 예제에 사용된 ISampleService에 대해 생성된 구성 파일에는 다음과 같은 엔드포인트 정보가 포함되어 있습니다.

<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
                name="WSHttpBinding_ISampleService">
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

이 구성 파일은 <client> 요소에서 대상 엔드포인트를 지정합니다. 여러 대상 엔드포인트를 사용하는 방법에 대한 자세한 내용은 ClientBase<TChannel> 또는 ChannelFactory<TChannel> 생성자를 참조하세요.

작업 호출

클라이언트 개체를 만들어 구성한 후 try/catch 블록을 만들고 로컬 개체에 대해서와 같은 방법으로 작업을 호출한 다음 WCF 클라이언트 개체를 닫습니다. 클라이언트 애플리케이션이 첫 번째 작업을 호출하면 WCF에서 기본 채널을 자동으로 엽니다. 개체가 재생되면 기본 채널이 닫힙니다. 또는 다른 작업을 호출하기 이전 또는 이후에 채널을 명시적으로 열었다가 닫을 수 있습니다.

예를 들어, 다음과 같은 서비스 계약을 가정해 봅니다.

namespace Microsoft.ServiceModel.Samples  
{  
    using System;  
    using System.ServiceModel;  
  
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]  
    public interface ICalculator  
   {  
        [OperationContract]  
        double Add(double n1, double n2);  
        [OperationContract]  
        double Subtract(double n1, double n2);  
        [OperationContract]  
        double Multiply(double n1, double n2);  
        [OperationContract]  
        double Divide(double n1, double n2);  
    }  
}  
Namespace Microsoft.ServiceModel.Samples  
  
    Imports System  
    Imports System.ServiceModel  
  
    <ServiceContract(Namespace:= _  
    "http://Microsoft.ServiceModel.Samples")> _
   Public Interface ICalculator  
        <OperationContract> _
        Function Add(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Subtract(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
        Function Multiply(n1 As Double, n2 As Double) As Double  
        <OperationContract> _
     Function Divide(n1 As Double, n2 As Double) As Double  
End Interface  

다음 코드 예제에 설명된 것처럼 WCF 클라이언트 개체를 만든 다음 해당 메서드를 호출하여 작업을 호출할 수 있습니다. WCF 클라이언트 개체 열기, 호출, 닫기는 단일 try/catch 블록 내에서 발생합니다. 자세한 내용은 WCF 클라이언트를 사용하여 서비스에 액세스닫기 및 중단을 사용하여 WCF 클라이언트 리소스 해제를 참조하세요.

CalculatorClient wcfClient = new CalculatorClient();
try
{
    Console.WriteLine(wcfClient.Add(4, 6));
    wcfClient.Close();
}
catch (TimeoutException timeout)
{
    // Handle the timeout exception.
    wcfClient.Abort();
}
catch (CommunicationException commException)
{
    // Handle the communication exception.
    wcfClient.Abort();
}

오류 처리

기본 클라이언트 채널을 명시적으로 열거나 작업을 호출하여 자동으로 열 때, 클라이언트 또는 채널 개체를 사용하여 작업을 호출할 경우 또는 기본 클라이언트 채널을 닫을 때 클라이언트 애플리케이션에서 예외가 발생할 수 있습니다. 적어도 애플리케이션에서 가능한 System.TimeoutExceptionSystem.ServiceModel.CommunicationException 예외를 비롯하여 작업에서 반환되는 SOAP 오류로 인해 throw되는 System.ServiceModel.FaultException 개체를 처리하도록 하는 것이 좋습니다. 작업 계약에 지정된 SOAP 오류는 형식 매개 변수가 SOAP 오류의 세부 유형인 System.ServiceModel.FaultException<TDetail>으로, 클라이언트 애플리케이션에서 발생됩니다. 클라이언트 애플리케이션에서 오류 조건을 처리하는 방법에 대한 자세한 내용은 오류 보내기 및 받기를 참조하세요. 클라이언트에서 오류를 처리하는 방법을 보여 주는 전체 샘플을 보려면 예상되는 예외를 참조하세요.

클라이언트 구성 및 보안

클라이언트를 구성하려면 클라이언트 생성자와 속성을 사용하여 클라이언트 또는 채널 개체에 대한 대상 엔드포인트 정보를 프로그래밍 방식으로 로드할 수도 있지만, 일반적으로 구성 파일에서 이 정보를 로드해야 합니다. 그러나 다양한 보안 시나리오에 대해 특정 클라이언트 동작을 활성화하는 추가 구성 단계를 수행해야 합니다.

예를 들어, 서비스 계약에 대한 보안 요구 사항이 서비스 계약 인터페이스에 선언되어 있고, Svcutil.exe에서 구성 파일을 만든 경우 해당 파일에는 일반적으로 서비스의 보안 요구 사항을 지원할 수 있는 바인딩이 포함되어 있습니다. 그러나, 클라이언트 자격 증명 구성처럼 추가 보안 구성이 필요한 경우도 있습니다. 클라이언트의 보안 구성에 대한 자세한 내용은 클라이언트에 보안 설정을 참조하세요.

또한 클라이언트 애플리케이션에서 사용자 지정 런타임 동작과 같은 사용자 지정 수정을 사용할 수 있는 경우도 있습니다. 사용자 지정 클라이언트 동작을 구성하는 방법에 대한 자세한 내용은 클라이언트 동작 구성을 참조하세요.

이중 서비스에 대한 콜백 개체 만들기

이중 서비스는 계약 요구 사항에 따라 서비스를 호출하도록 콜백 개체를 제공하기 위해 클라이언트 애플리케이션에서 구현해야 하는 콜백 계약을 지정합니다. 콜백 개체는 정식 서비스가 아니지만(예를 들어, 콜백 개체를 사용하여 채널을 시작할 수 없음) 구현 및 구성을 위해 일종의 서비스로 간주될 수 있습니다.

이중 서비스의 클라이언트는 다음을 수행해야 합니다.

  • 콜백 계약 클래스 구현

  • 콜백 계약 구현 클래스의 인스턴스를 만든 다음, 해당 인스턴스를 사용하여 WCF 클라이언트 생성자에 전달할 System.ServiceModel.InstanceContext 개체를 만듭니다.

  • 작업 호출 및 작업 콜백 처리

이중 WCF 클라이언트 개체는 콜백 서비스 구성을 포함하여 콜백을 지원하는 데 필요한 기능을 노출한다는 점만 제외하고 비이중 클라이언트 개체와 같은 역할을 합니다.

예를 들어, 콜백 클래스에서 System.ServiceModel.CallbackBehaviorAttribute 특성의 속성을 사용하여 콜백 개체 런타임 동작을 다양하게 제어할 수 있습니다. 또 다른 예로, System.ServiceModel.Description.CallbackDebugBehavior 클래스를 사용하여 콜백 개체를 호출하는 서비스에 예외 정보를 반환할 수 있습니다. 자세한 내용은 이중 서비스를 참조하세요. 전체 샘플은 이중을 참조하세요.

IIS(인터넷 정보 서비스) 5.1을 실행하는 Windows XP 컴퓨터에서 이중 클라이언트는 System.ServiceModel.WSDualHttpBinding 클래스를 사용하여 클라이언트 기본 주소를 지정해야 합니다. 그렇지 않으면 예외가 throw됩니다. 다음 코드 예제에서는 코드에서 이 작업을 수행하는 방법을 보여 줍니다.

WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");

Dim dualBinding As New WSDualHttpBinding()
Dim endptadr As New EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server")
dualBinding.ClientBaseAddress = New Uri("http://localhost:8000/DuplexTestUsingCode/Client/")

다음 코드에서는 구성 파일에서 이 작업을 수행하는 방법을 보여 줍니다.

<client>
  <endpoint
    name ="ServerEndpoint"
    address="http://localhost:12000/DuplexUsingConfig/Server"
    bindingConfiguration="WSDualHttpBinding_IDuplex"
    binding="wsDualHttpBinding"
    contract="IDuplex"
/>
</client>
<bindings>
  <wsDualHttpBinding>
    <binding
      name="WSDualHttpBinding_IDuplex"
      clientBaseAddress="http://localhost:8000/myClient/"
    />
  </wsDualHttpBinding>
</bindings>

비동기적으로 서비스 호출

작업이 호출되는 방법은 클라이언트 개발자에 의해 지정됩니다. 작업을 구성하는 메시지는 관리되는 코드에 표시될 때 동기 메서드나 비동기 메서드에 매핑될 수 있기 때문입니다. 따라서 작업을 비동기적으로 호출하는 클라이언트를 빌드하려면 Svcutil.exe에서 /async 옵션을 사용하여 비동기 클라이언트 코드를 생성할 수 있습니다. 자세한 내용은 방법: 비동기적으로 서비스 작업 호출을 참조하세요.

WCF 클라이언트 채널을 사용하여 서비스 호출

WCF 클라이언트 형식은 ClientBase<TChannel>를 확장합니다. 이 형식은 System.ServiceModel.IClientChannel 인터페이스에서 직접 파생되어 기본 채널 시스템을 노출합니다. System.ServiceModel.ChannelFactory<TChannel> 클래스와의 대상 서비스 계약을 사용하여 서비스를 호출할 수 있습니다. 자세한 내용은 WCF 클라이언트 아키텍처를 참조하세요.

참고 항목