중욯 : https://blog.naver.com/techshare/220725308257
http://sysnet.pe.kr/220724464263
https://blog.naver.com/techshare/220725308257
이유는 간단합니다. 해당 IService1.GetData 메서드의 코드를 보면,
public string GetData(int value)
{
IService1Callback _callback = OperationContext.Current.GetCallbackChannel();
{
Thread.Sleep(value * 1000);
_callback.Finished(true);
return string.Format("You entered: {0}", value);
}
}
_callback.Finished 호출이 발생하는 데 그 순간 Socket.Connect("testpc") 호출이 발생하지만 "testpc"에 대한 IP 해석이 되지 않아 Socket Connection timeout이 발생하기까지 대기하게 되고 이 때문에 WCF의 기본 timeout 값에 걸려 "The open operation did not complete within the allotted timeout of 00:00:59.9979992"와 같은 오류 메시지가 발생하는 것입니다.
경험이 없는 WCF 개발자라면, 이 오류 메시지를 보고 WCF timeout 관련 설정을 조정하겠지만 그것으로 해결될 문제가 아닙니다. 더욱 문제는, 이에 대해 WCF를 호스팅하는 IIS 서비스 측에서 이벤트 로그 등을 통한 오류 흔적이 전혀 안 남는다는 점입니다.
이 오류를 쉽게 감지하는 것은 WCF 로깅을 사용하거나 지난 번에 알려드린 procdump를 이용해 보면 됩니다.
try/catch로 조용히 사라진 예외를 파악하고 싶다면?
; http://www.sysnet.pe.kr/2/0/10965
가령, procdump.exe를 이용하는 경우 다음과 같은 오류 메시지가 발생하는 것을 확인할 수 있습니다.
[21:05:05] Exception: E0434F4D.System.Net.WebException ("The remote name could not be resolved: 'testpc'")
[21:05:05] Exception: E0434F4D.System.ServiceModel.EndpointNotFoundException ("There was no endpoint listening at http://testpc/Temporary_Listen_Addresses/1f1be8f1-d610-4797-840c-07ebdbfd3ad1/7e5a35b9-1d00-4a15-9a46-585798e347da that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.")
[21:05:05] Exception: E0434F4D.System.ServiceModel.CommunicationException ("The inactivity timeout of (00:10:00) has been exceeded.")
[21:05:05] Exception: E0434F4D.System.ServiceModel.CommunicationObjectFaultedException ("The communication object, System.ServiceModel.Channels.ServerReliableDuplexSessionChannel, cannot be used for communication because it is in the Faulted state.")
바로 이런 경우처럼, WCF가 자동으로 넘겨주는 "Temporary_Listen_Addresses" 주소를 WCF 서비스 측에서 콜백 호출 시 아무런 문제가 없도록 하는 방법이 ClientBaseAddress를 지정해 주는 것입니다.
이 글의 예에서는 VPN에 알려진 클라이언트 측의 IP 주소를 192.168.10.22라고 가정했을 때 다음과 같이 바인딩 정보를 지정하면 됩니다.
이렇게 바꾸고 WCF 호출을 하면, 서버 측에서는 클라이언트가 새롭게 전달해 준 "http://192.168.10.22/Temporary_Listen_Addresses/.../..." 주소로 역방향 호출을 하게 되고 결과적으로 서비스가 정상적으로 운영이 됩니다.
[출처] C# - WCF wsDualHttpBinding의 ClientBaseAddress 속성|작성자 techshare
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
// 참고: "리팩터링" 메뉴에서 "이름 바꾸기" 명령을 사용하여 코드, svc 및 config 파일에서 클래스 이름 "Service1"을 변경할 수 있습니다.
// 참고: 이 서비스를 테스트하기 위해 WCF 테스트 클라이언트를 시작하려면 솔루션 탐색기에서Service1.svc나 Service1.svc.cs를 선택하고 디버깅을 시작하십시오.
public class Service1 : IService1
{
static IService1Callback callback = null;
static IService1Callback callback2 = null;
public string GetData(int value)
{
if(callback == null && value == 1)
callback = OperationContext.Current.GetCallbackChannel<IService1Callback>();
if (callback2 == null && value == 2)
callback2 = OperationContext.Current.GetCallbackChannel<IService1Callback>();
System.Threading.Thread.Sleep(value * 100);
if (callback != null)
callback.Finished(true);
if (callback2 != null)
callback2.Finished(true);
/*
callback.Finished(true); // 이 메서드를 호출한 클라이언트 측의 Finished 메서드를 호출
[출처] C# - wsDualHttpBinding WCF 예제 프로그램|작성자 techshare
*/
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}