C# - wsDualHttpBinding WCF 예제 프로그램 - 양방향

seung-jae hwang·2019년 3월 20일
0

Csharp

목록 보기
6/8

중욯 : https://blog.naver.com/techshare/220725308257

http://sysnet.pe.kr/220724464263

https://blog.naver.com/techshare/220725308257

http://blog.naver.com/PostView.nhn?blogId=techshare&logNo=220724464263&parentCategoryNo=&categoryNo=1&viewDate=&isShowPopularPosts=true&from=search

이유는 간단합니다. 해당 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;
    }
}

}

0개의 댓글