WCF(Windows Communication Foundation) 서비스와 같은 WCF(Windows Communication Foundation) 클라이언트는 클라이언트 애플리케이션에 맞게 런타임 동작을 수정하도록 구성할 수 있습니다. 클라이언트 런타임 동작을 지정하는 데 세 가지 특성을 사용할 수 있습니다. 이중 클라이언트 콜백 개체는 CallbackBehaviorAttribute 및 CallbackDebugBehavior 특성을 사용하여 런타임 동작을 수정할 수 있습니다. 다른 특성은 ClientViaBehavior논리 대상을 직접 네트워크 대상과 구분하는 데 사용할 수 있습니다. 또한 이중 클라이언트 콜백 형식은 서비스 쪽 동작 중 일부를 사용할 수 있습니다. 자세한 내용은 서비스 Run-Time 동작 지정을 참조하세요.
CallbackBehaviorAttribute 사용
클래스를 사용하여 클라이언트 애플리케이션에서 콜백 계약 구현의 실행 동작을 구성하거나 확장할 CallbackBehaviorAttribute 수 있습니다. 이 특성은 인스턴스화 동작 및 트랜잭션 설정을 제외하고 콜백 클래스 ServiceBehaviorAttribute 에 대해 클래스와 유사한 함수를 수행합니다.
CallbackBehaviorAttribute 콜백 계약을 구현하는 클래스에 클래스를 적용해야 합니다. 비듀플렉스 계약 구현에 적용되는 경우 런타임에 InvalidOperationException 예외가 throw됩니다. 다음 코드 예제는 콜백 개체의 CallbackBehaviorAttribute 클래스가 SynchronizationContext 개체를 사용하여 마샬링할 스레드를 결정하는 방법, ValidateMustUnderstand 속성을 사용하여 메시지 유효성 검사를 적용하는 방법, 및 IncludeExceptionDetailInFaults 속성을 사용하여 예외를 디버깅 목적으로 FaultException 개체로 서비스에 반환하는 방법을 보여줍니다.
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;
namespace Microsoft.WCF.Documentation
{
[CallbackBehaviorAttribute(
IncludeExceptionDetailInFaults= true,
UseSynchronizationContext=true,
ValidateMustUnderstand=true
)]
public class Client : SampleDuplexHelloCallback
{
AutoResetEvent waitHandle;
public Client()
{
waitHandle = new AutoResetEvent(false);
}
public void Run()
{
// Picks up configuration from the configuration file.
SampleDuplexHelloClient wcfClient
= new SampleDuplexHelloClient(new InstanceContext(this), "WSDualHttpBinding_SampleDuplexHello");
try
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Enter a greeting to send and press ENTER: ");
Console.Write(">>> ");
Console.ForegroundColor = ConsoleColor.Green;
string greeting = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Called service with: \r\n\t" + greeting);
wcfClient.Hello(greeting);
Console.WriteLine("Execution passes service call and moves to the WaitHandle.");
this.waitHandle.WaitOne();
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Set was called.");
Console.Write("Press ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("ENTER");
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write(" to exit...");
Console.ReadLine();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
}
}
public static void Main()
{
Client client = new Client();
client.Run();
}
public void Reply(string response)
{
Console.WriteLine("Received output.");
Console.WriteLine("\r\n\t" + response);
this.waitHandle.Set();
}
}
}
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Threading
Namespace Microsoft.WCF.Documentation
<CallbackBehaviorAttribute(IncludeExceptionDetailInFaults:=True, UseSynchronizationContext:=True, ValidateMustUnderstand:=True)> _
Public Class Client
Implements SampleDuplexHelloCallback
Private waitHandle As AutoResetEvent
Public Sub New()
waitHandle = New AutoResetEvent(False)
End Sub
Public Sub Run()
' Picks up configuration from the configuration file.
Dim wcfClient As New SampleDuplexHelloClient(New InstanceContext(Me), "WSDualHttpBinding_SampleDuplexHello")
Try
Console.ForegroundColor = ConsoleColor.White
Console.WriteLine("Enter a greeting to send and press ENTER: ")
Console.Write(">>> ")
Console.ForegroundColor = ConsoleColor.Green
Dim greeting As String = Console.ReadLine()
Console.ForegroundColor = ConsoleColor.White
Console.WriteLine("Called service with: " & Constants.vbCrLf & Constants.vbTab & greeting)
wcfClient.Hello(greeting)
Console.WriteLine("Execution passes service call and moves to the WaitHandle.")
Me.waitHandle.WaitOne()
Console.ForegroundColor = ConsoleColor.Blue
Console.WriteLine("Set was called.")
Console.Write("Press ")
Console.ForegroundColor = ConsoleColor.Red
Console.Write("ENTER")
Console.ForegroundColor = ConsoleColor.Blue
Console.Write(" to exit...")
Console.ReadLine()
Catch timeProblem As TimeoutException
Console.WriteLine("The service operation timed out. " & timeProblem.Message)
Console.ReadLine()
Catch commProblem As CommunicationException
Console.WriteLine("There was a communication problem. " & commProblem.Message)
Console.ReadLine()
End Try
End Sub
Public Shared Sub Main()
Dim client As New Client()
client.Run()
End Sub
Public Sub Reply(ByVal response As String) Implements SampleDuplexHelloCallback.Reply
Console.WriteLine("Received output.")
Console.WriteLine(Constants.vbCrLf & Constants.vbTab & response)
Me.waitHandle.Set()
End Sub
End Class
End Namespace
CallbackDebugBehavior를 사용하여 관리되는 예외 정보의 흐름 사용
프로퍼티를 프로그래밍 방식이나 애플리케이션 구성 파일에서 설정하여, 디버깅을 목적으로 클라이언트 콜백 객체의 관리되는 예외 정보가 서비스로 다시 전송되도록 흐름을 활성화할 수 있습니다.
예외 세부 정보는 권한이 없는 서비스에서 사용할 수 있는 내부 클라이언트 구현에 대한 정보를 노출하므로 관리되는 예외 정보를 서비스에 반환하는 것은 보안 위험이 될 수 있습니다. 또한 속성은 프로그램을 통해 설정할 수도 있지만, 배포 시 CallbackDebugBehavior을(를) 사용하지 않도록 설정하는 것을 잊기 쉽습니다.
관련된 보안 문제로 인해 다음을 수행하는 것이 좋습니다.
애플리케이션 구성 파일을 사용하여 속성 IncludeExceptionDetailInFaults값을
true
.로 설정합니다.제어된 디버깅 시나리오에서만 이 작업을 수행합니다.
다음 코드 예제에서는 SOAP 메시지의 클라이언트 콜백 개체에서 관리되는 예외 정보를 반환하도록 WCF에 지시하는 클라이언트 구성 파일을 보여 줍니다.
<client>
<endpoint
address="http://localhost:8080/DuplexHello"
binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_SampleDuplexHello"
contract="SampleDuplexHello"
name="WSDualHttpBinding_SampleDuplexHello"
behaviorConfiguration="enableCallbackDebug">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="enableCallbackDebug">
<callbackDebug includeExceptionDetailInFaults="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
ClientViaBehavior 동작의 사용
이 동작을 ClientViaBehavior 사용하여 전송 채널을 만들어야 하는 Uniform Resource Identifier를 지정할 수 있습니다. 즉각적인 네트워크 대상이 메시지의 의도된 프로세서가 아닌 경우 이 동작을 사용합니다. 이렇게 하면 호출 애플리케이션이 최종 대상을 반드시 알지 못하거나 대상 Via
헤더가 주소가 아닌 경우 다중 홉 대화를 사용할 수 있습니다.