다음을 통해 공유


클라이언트를 사용하여 서비스 액세스

클라이언트 애플리케이션은 서비스와 통신할 WCF 클라이언트 또는 채널 개체를 만들고 구성 및 사용해야 합니다. WCF 클라이언트 개요 항목에서는 기본 클라이언트 및 채널 개체를 만들고 사용하는 데 관련된 단계와 개체에 대한 개요를 제공합니다.

이 항목에서는 시나리오에 따라 유용할 수 있는 클라이언트 및 채널 개체와 클라이언트 애플리케이션과 관련된 몇 가지 문제에 대한 자세한 정보를 제공합니다.

개요

이 항목에서는 다음과 관련된 동작 및 문제에 대해 설명합니다.

  • 채널 및 세션 수명

  • 예외 처리

  • 블로킹 문제 이해

  • 대화형으로 채널 초기화

채널 및 세션 수명

WCF(Windows Communication Foundation) 애플리케이션에는 데이터그램과 세션이라는 두 가지 범주의 채널이 있습니다.

데이터그램 채널은 모든 메시지가 상호 관련되지 않은 채널입니다. 데이터그램 채널을 사용할 경우 입력 또는 출력 작업이 실패해도 일반적으로 다음 작업이 영향을 받지 않으며 동일한 채널을 다시 사용할 수 있습니다. 이 때문에 데이터그램 채널은 실패하지 않습니다.

그러나 세션 채널은 다른 엔드포인트에 연결된 채널입니다. 한쪽의 세션 메시지는 항상 다른 쪽의 동일한 세션과 상호 관련됩니다. 또한 한 세션이 성공한 것으로 간주되려면 해당 세션의 두 참가자가 모두 대화 요구 사항이 충족되었다고 동의해야 합니다. 동의할 수 없는 경우 세션 채널이 실패할 수 있습니다.

첫 번째 작업을 호출하여 명시적 또는 암시적으로 클라이언트를 엽니다.

참고 항목

알림을 받는 시기가 세션 구현에 따라 달라지므로 실패한 세션 채널을 명시적으로 검색하려는 시도는 일반적으로 유용하지 않습니다. 예를 들어 신뢰할 수 있는 세션을 사용하지 않는 System.ServiceModel.NetTcpBinding은 TCP 연결의 세션을 표시하므로 서비스 또는 클라이언트의 ICommunicationObject.Faulted 이벤트를 수신 대기하면 네트워크 오류가 발생할 경우 신속하게 알림을 받습니다. 그러나 System.ServiceModel.Channels.ReliableSessionBindingElement를 사용하는 바인딩으로 설정된 신뢰할 수 있는 세션은 소규모 네트워크 오류로부터 서비스를 분리합니다. 적절한 기간 내에 세션을 다시 설정할 수 있는 경우 보다 긴 기간 동안 중단이 계속될 때까지 신뢰할 수 있는 세션에 대해 구성된 동일한 바인딩이 실패하지 않습니다.

채널을 애플리케이션 계층에 노출하는 대부분의 시스템 제공 바인딩은 기본적으로 세션을 사용하지만 System.ServiceModel.BasicHttpBinding은 사용하지 않습니다. 자세한 내용은 세션 사용을 참조하세요.

적절한 세션 사용

세션은 전체 메시지 교환이 완료되었는지 여부 및 양쪽에서 성공했다고 간주하는지 여부를 확인하는 방법을 제공합니다. 호출 애플리케이션은 하나의 try 블록 내에서 채널을 열고 사용한 후 닫는 것이 좋습니다. 세션 채널이 열려 있고 ICommunicationObject.Close 메서드를 한 번 호출한 후 해당 호출이 성공적으로 반환되면 세션이 성공했습니다. 이 경우 성공은 바인딩에서 지정한 모든 배달 보증이 충족되었으며 다른 쪽이 ICommunicationObject.Abort를 호출하기 전에 채널에서 Close를 호출하지 않았음을 의미합니다.

다음 섹션에서는 이 클라이언트 접근 방법의 예를 제공합니다.

예외 처리

클라이언트 애플리케이션의 예외 처리는 단순합니다. 하나의 try 블록 내에서 채널을 열고 사용한 후 닫으면 예외가 throw되지 않는 한 대화가 성공합니다. 일반적으로 예외가 throw되면 대화가 중단됩니다.

참고 항목

using 문(Visual Basic의 경우 Using)은 사용하지 않는 것이 좋습니다. 이는 using 문의 끝에서 예외가 발생하여 사용자가 확인해야 하는 다른 예외를 마스킹할 수 있기 때문입니다. 자세한 내용은 닫기 및 중단을 사용하여 WCF 클라이언트 리소스 해제를 참조하세요.

다음 코드 예제에서는 using 문이 아니라 try/catch 블록을 사용한 권장되는 클라이언트 패턴을 보여 줍니다.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;

public class Client
{
  public static void Main()
  {
    // Picks up configuration from the config file.
    SampleServiceClient wcfClient = new SampleServiceClient();
    try
    {
      // Making calls.
      Console.WriteLine("Enter the greeting to send: ");
      string greeting = Console.ReadLine();
      Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));

      Console.WriteLine("Press ENTER to exit:");
      Console.ReadLine();

      // Done with service.
      wcfClient.Close();
      Console.WriteLine("Done!");
    }
    catch (TimeoutException timeProblem)
    {
      Console.WriteLine("The service operation timed out. " + timeProblem.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException<GreetingFault> greetingFault)
    {
      Console.WriteLine(greetingFault.Detail.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (FaultException unknownFault)
    {
      Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
      Console.ReadLine();
      wcfClient.Abort();
    }
    catch (CommunicationException commProblem)
    {
      Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
      Console.ReadLine();
      wcfClient.Abort();
    }
  }
}

Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports Microsoft.WCF.Documentation

Public Class Client
    Public Shared Sub Main()
        ' Picks up configuration from the config file.
        Dim wcfClient As New SampleServiceClient()
        Try
            ' Making calls.
            Console.WriteLine("Enter the greeting to send: ")
            Dim greeting As String = Console.ReadLine()
            Console.WriteLine("The service responded: " & wcfClient.SampleMethod(greeting))

            Console.WriteLine("Press ENTER to exit:")
            Console.ReadLine()

            ' Done with service. 
            wcfClient.Close()
            Console.WriteLine("Done!")
        Catch timeProblem As TimeoutException
            Console.WriteLine("The service operation timed out. " & timeProblem.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch greetingFault As FaultException(Of GreetingFault)
            Console.WriteLine(greetingFault.Detail.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch unknownFault As FaultException
            Console.WriteLine("An unknown exception was received. " & unknownFault.Message)
            Console.ReadLine()
            wcfClient.Abort()
        Catch commProblem As CommunicationException
            Console.WriteLine("There was a communication problem. " & commProblem.Message + commProblem.StackTrace)
            Console.ReadLine()
            wcfClient.Abort()
        End Try
    End Sub
End Class

참고 항목

ICommunicationObject.State 속성 값 확인은 경합 상태이며 채널을 다시 사용할지 또는 닫을지 결정하는 데 사용하지 않는 것이 좋습니다.

데이터그램 채널은 닫을 때 예외가 발생하는 경우에도 실패하지 않습니다. 또한 보안 대화를 사용하여 인증할 수 없는 비이중 클라이언트는 일반적으로 System.ServiceModel.Security.MessageSecurityException을 throw합니다. 그러나 보안 대화를 사용하는 이중 클라이언트가 인증할 수 없는 경우 클라이언트는 대신 System.TimeoutException을 수신합니다.

애플리케이션 수준에서 오류 정보 작업에 대한 자세한 내용은 계약 및 서비스의 오류 지정 및 처리를 참조하세요. 예상된 예외는 예상되는 예외를 설명하고 처리 방법을 보여 줍니다. 채널을 개발할 때 발생하는 오류를 처리하는 방법에 대한 자세한 내용은 예외 및 오류 처리를 참조하세요.

클라이언트 차단 및 성능

애플리케이션에서 동기적으로 request-reply 작업을 호출하는 경우 클라이언트는 반환 값이 수신되거나 System.TimeoutException 같은 예외가 throw될 때까지 차단됩니다. 이 동작은 로컬 동작과 유사합니다. 애플리케이션이 WCF 클라이언트 개체나 채널에서 동기적으로 작업을 호출하는 경우 클라이언트는 채널 계층이 데이터를 네트워크에 쓸 수 있을 때까지 또는 예외가 throw될 때까지 반환되지 않습니다. OperationContractAttribute.IsOneWaytrue로 설정하여 작업을 표시함으로써 지정된 단방향 메시지 교환 패턴은 일부 클라이언트의 응답을 향상시키지만 바인딩 및 이미 전송된 메시지에 따라 단방향 작업이 차단될 수도 있습니다. 단방향 작업은 메시지 교환에만 사용됩니다. 자세한 내용은 편도 서비스를 참조하세요.

큰 데이터 청크는 메시지 교환 패턴에 관계없이 클라이언트 처리 속도를 저하시킬 수 있습니다. 이러한 문제를 처리하는 방법을 이해하려면 대용량 데이터 및 스트리밍을 참조하세요.

작업이 완료되는 동안 애플리케이션에서 추가 작업을 수행해야 하는 경우 WCF 클라이언트가 구현하는 서비스 계약 인터페이스에 비동기 메서드 쌍을 만들어야 합니다. 이를 수행하는 가장 쉬운 방법은 ServiceModel 메타데이터 유틸리티 도구(Svcutil.exe)에서 /async 스위치를 사용하는 것입니다. 예를 들어 방법: 비동기식으로 서비스 작업 호출을 참조하세요.

클라이언트 성능 향상에 대한 자세한 내용은 중간 계층 클라이언트 애플리케이션을 참조하세요.

사용자가 동적으로 자격 증명을 선택할 수 있도록 설정

IInteractiveChannelInitializer 인터페이스를 사용하면 애플리케이션이 시간 제한 타이머가 시작되기 전에 채널을 만드는 데 사용할 자격 증명을 사용자가 선택할 수 있도록 하는 사용자 인터페이스를 표시할 수 있습니다.

애플리케이션 개발자는 삽입된 IInteractiveChannelInitializer를 두 가지 방법으로 사용할 수 있습니다. 클라이언트 애플리케이션은 채널을 열기 전에 ClientBase<TChannel>.DisplayInitializationUI 또는 IClientChannel.DisplayInitializationUI(또는 비동기 버전)를 호출하거나(명시적 방법) 첫 번째 작업만을 호출할 수 있습니다(암시적 방법).

암시적 방법을 사용하는 경우 애플리케이션은 ClientBase<TChannel> 또는 IClientChannel 확장에서 첫 번째 작업을 호출해야 합니다. 첫 번째 작업 이외의 다른 작업을 호출하면 예외가 throw됩니다.

명시적 방법을 사용하는 경우 애플리케이션은 다음 단계를 순서대로 수행해야 합니다.

  1. ClientBase<TChannel>.DisplayInitializationUI 또는 IClientChannel.DisplayInitializationUI(또는 비동기 버전)를 호출합니다.

  2. 이니셜라이저가 반환되면 ClientBase<TChannel>.InnerChannel 속성에서 반환된 IClientChannel 개체 또는 IClientChannel 개체에서 Open 메서드를 호출합니다.

  3. 작업을 호출합니다.

프로덕션 품질 애플리케이션에서는 명시적 방법을 사용하여 사용자 인터페이스 프로세스를 제어하는 것이 좋습니다.

암시적 방법을 사용하는 애플리케이션은 사용자 인터페이스 이니셜라이저를 호출하지만, 애플리케이션 사용자가 바인딩에 대한 전송 시간 제한 내에 응답하지 않을 경우 사용자 인터페이스가 반환될 때 예외가 throw됩니다.

참고 항목