Microsoft MVP성태의 닷넷 이야기
.NET Framework: 74.1. WCF와 WSE 3.0의 활용 [링크 복사], [링크+제목 복사],
조회: 28907
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
부모글 보이기/감추기
(연관된 글이 2개 있습니다.)
1. WCF와 WSE 3.0의 활용


시나리오를 하나 예로 들어볼까요?

ASP.NET처럼 요청/응답 형의 서버 프로그램이 아니라, NT 서비스(데몬) 성격의 프로그램을 만들어야 되는 상황을 가정해 봅시다. 이때, 여러분들은 해당 NT 서비스 내부에서 행해지는 기능들 또는 직접적인 데이터들에 대해 외부 EXE 프로그램에 노출시켜 주고 싶습니다.
이제 한번 생각해 볼까요?... 이때 여러분들은 어떤 식으로 Application 구조를 잡으시겠습니까?

아마도 WSE 3.0과 WCF를 모르시는 분들은 대개 다음과 같은 식으로 응용 프로그램 구조를 잡으실 것 같습니다.

[그림 1: IIS 서비스를 경유하여 웹 서비스 제공]
IIS 서비스를 경유하여 웹 서비스 제공

물론, NT 서비스 측에서 바로 서버 소켓을 대기시켜 놓고 클라이언트 응용 프로그램에서 접근하게 하는 것도 방법일 테고요. 그런 경우는 특별하게 속도를 염두에 두지 않고는 요즘같은 Enterprise App 세계에서는 효율적이지 않기 때문에 고려 대상에서 제외가 되지요.



상황이 바뀌어서, 여러분들이 만약 WSE 3.0 또는 WCF를 아는 분들이라면, 다음과 같은 응용 프로그램 구조도 가능하다는 것을 알 수 있습니다.

[그림 2: 스스로 웹 서비스 제공]
스스로 웹 서비스 제공

즉, WCF와 WSE 3.0의 경우에는 웹 서비스 기능을 직접 호스팅 할 수 있는 구조를 갖게 됩니다. WSE 3.0은 이미 정식 버전이 나온 상태이고 향후의 WCF와도 호환을 보장한다고 하니 WCF를 기다릴 수 없는 분들은 WSE 3.0을 사용하는 것도 좋은 선택일 수 있습니다. (하지만, .NET 3.0 RC2가 나온 데다 10월 25일에 Vista RTM 버전이 나온다고 하니, .NET 3.0 정식 버전도 그 안에 마무리 되지 않을까 예상해 봅니다.)



기왕에 정리하는 것이니, 코드가 없으면 심심하겠지요! ^^
간단하게, WCF와 WSE 3.0의 Console 버전에서 웹 서비스를 호스팅하고 사용하는 방법에 대해 정리해 보도록 하겠습니다.

#. WSE 3.0 콘솔 서비스와 클라이언트 제작

[WSE 3.0 서비스 제작]
1. WSE 3.0 SDK를 아래의 링크에서 다운로드 받아 설치합니다.
Web Services Enhancements (WSE) 3.0 for Microsoft .NET
; http://www.microsoft.com/downloads/details.aspx?familyid=018a09fd-3a74-43c5-8ec1-8d789091255d&displaylang=en

2. VS.NET 2005를 실행시키고 새로운 프로젝트를 생성합니다. 여기서는 "WSE30Console"이라는 콘솔 유형의 프로젝트를 생성한 것으로 예를 들겠습니다. 비록, 예제는 콘솔 응용 프로그램이지만 동일한 방식으로 NT Service나 WinForm 응용 프로그램에 코드를 적용할 수 있습니다.

3. 솔루션 탐색기 창에서 해당 "WSE30Console" 프로젝트 노드를 오른쪽 마우스 버튼으로 클릭하면 "WSE Settings 3.0..."이라는 메뉴가 나오고 선택하면 다음과 같은 설정창이 뜹니다.

WSE 3.0 설정 대화창

4. 3번 단계를 거치면, 필요한 네임스페이스와 app.config이 정의되게 됩니다. 별다른 WSE 특징을 사용하지 않는다면 "Microsoft.Web.Services3.dll"을 참조 추가하는 것으로도 충분합니다. 이 외에, "System.Web.Services.dll"을 참조 추가해줍니다.

5. "Program.cs" 파일에 다음과 같이 using 문을 추가합니다.

using Microsoft.Web.Services3.Messaging;
using Microsoft.Web.Services3.Addressing;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;

6. "Program.cs"에 다음과 같이 간단한 웹 서비스 클래스를 추가합니다.

  [WebService(Namespace = "http://test.com")]
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  public class HelloService : System.Web.Services.WebService
  {
    public HelloService()
    {
    }

    [WebMethod]
    public string HelloWorld()
    {
      return "Hello World";
    }
  }

7. 마지막으로, 6번 과정에서 정의된 서비스를 호스팅하는 코드를 Main에 작성합니다. 기본적으로 아래와 같이 경로에 포트를 명시하지 않으면 8081 포트에서 대기를 하게 됩니다. 이때, SoapReceivers.Add의 인자로 HTTP 주소 방식을 사용할 수 없습니다. 왜냐하면, WSE 3.0은 HTTP.sys와의 직접적인 통합을 제공하지 않기 때문입니다.

    static void Main(string[] args)
    {
      Uri listenAddress = new Uri("soap.tcp://localhost/HelloService");
      SoapReceivers.Add(new EndpointReference(listenAddress),
        typeof(HelloService));

      Console.WriteLine("Press any key to exit...");
      Console.ReadLine();
    }

여기까지, 여러분들은 WSE 3.0을 이용해서 웹 서비스를 Console 응용 프로그램에서 호스팅하는 서버를 만든 것입니다. 이제 이렇게 Console 안에서 정의된 서비스를 이용하는 클라이언트 프로그램을 제작해 보도록 하겠습니다.





[WSE 3.0 클라이언트 제작]

1. 클라이언트용 콘솔 프로젝트를 새로 생성합니다. 여기서는 프로젝트 명을 "WSE30Consumer"라고 예를 들겠습니다.

2. 웹 서비스를 사용하는 것이니, 당연히 WSDL을 구할 수 있다면 좋겠지만, 지금 설명하는 방식은 SOAP 프로토콜을 사용한 TCP 통신을 구현한 것이기 때문에, 일반적인 wsdl.exe로는 코드 생성을 할 수 없고 반드시 WSE 3.0에서 제공되는 wsewsdl3.exe라는 툴을 사용해서 소스 생성을 해야 합니다. 다음은 그 예입니다.

C:\Program Files\Microsoft WSE\v3.0\Tools>WseWsdl3.exe /type:webClient soap.tcp://localhost/HelloService
Web Services Enhancements 3.0 for Microsoft .NET.
 Copyright (c) Microsoft Corporation.

Microsoft (R) Web Services Description Language Utility
[Microsoft (R) .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\Program Files\Microsoft WSE\v3.0\Tools\HelloService.cs'.


3. 생성된 helloService.cs 파일을 WSE30Consumer 프로젝트에 포함시키고, 다음의 3가지 DLL을 참조 추가합니다.

  • Microsoft.Web.Services3
  • System.Web.Services
  • System.Web

4. Program.cs 파일에 테스트를 위한 코드를 다음과 같이 작성합니다.

    static void Main(string[] args)
    {
      HelloService service = new HelloService();
      Console.WriteLine("Connect to " + service.Url);
      Console.WriteLine(service.HelloWorld());
    }

5. 마지막으로 컴파일 시킨 다음, 서버 및 클라이언트를 실행시키면 정상적으로 동작하는 것을 확인할 수 있습니다.



2. WCF 콘솔 서비스와 클라이언트 제작

WSE 3.0은 정식 버전이 나와 있는 상태이기 때문에 현재 사용하는 것에 무리는 없지만, 역시나 그 보다 더 나은 환경이 WCF에서 제공되기 때문에 .NET 3.0 런타임 및 RC2라는 부담이 없다면 고려해 보는 것도 좋을 것 같습니다.

[WCF 콘솔 서비스 제작]

1. WCF 서버 응용 프로그램을 제작하기 위해서는 최소한 .NET 3.0 Runtime이 설치되어져 있어야 합니다. 다음의 토픽을 참고해서 다운로드 받으십시오.

Vista 5728 관련 .NET 3.0 다운로드 (2006-10-17)
; http://www.microsoft.com/downloads/details.aspx?FamilyId=C6636E90-26E6-44E0-8780-5D3CCD3D94ED&displaylang=en

2. 서비스를 호스팅해주는 Console 프로젝트를 생성합니다. 여기서는 "WcfConsole"이라고 짓겠습니다.

3. "System.ServiceModel" 어셈블리를 참조 추가합니다.

4. "Program.cs" 파일에 "using System.ServiceModel;" 문을 추가합니다.

5. 아래와 같이 "Program.cs" 파일에 WCF 서비스 클래스를 추가합니다.

  [ServiceContract(Namespace = "http://www.wcftest.com/")]
  public interface IHelloWorld
  {
    [OperationContract]
    string HelloWorld();
  }

  [ServiceBehavior]
  public class CHelloWorld : IHelloWorld
  {
    public string HelloWorld()
    {
      return "Hello World";
    }
  }
  

6. Main 함수에 WCF 호스팅 코드를 추가합니다.

    static void Main(string[] args)
    {
      using (ServiceHost serviceHost = new ServiceHost(typeof(CHelloWorld)))
      {
        serviceHost.Open();
        Console.ReadLine();
        serviceHost.Close();
      }
    }

7. 마지막으로, "Application Configuration File", 즉 "app.config" 파일을 추가하고 다음의 내용을 추가하고 빌드합니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.serviceModel>
    
    <services>
      <service 
         name="WcfConsole.IHelloWorld"
         behaviorConfiguration="HelloWorldBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9091/HelloService"/>
          </baseAddresses>
        </host>
        <endpoint address=""
           binding="basicHttpBinding"
           contract="WcfConsole.IHelloWorld" />

        <endpoint address="mex"
                 binding="mexHttpBinding"
                 contract="IMetadataExchange" />
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="HelloWorldBehavior">
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    
  </system.serviceModel>

</configuration>





[WCF 클라이언트 제작]

1. WCF 클라이언트를 위해 이번에도 Console 프로젝트를 하나 추가합니다. 여기서는 "WcfConsumer"라고 이름 짓겠습니다.

2. 여기서부터 WCF와 WSE 3.0의 차이가 발생하게 됩니다. WSE 3.0에서는 Console에서 호스팅하는 경우 직접적으로 wsdl.exe와 같은 코드 생성 툴로는 소스 생성을 할 수 없었습니다. 하지만, WCF에서는 자체적으로 WSDL까지도 제공해주기 때문에 wsdl.exe뿐만 아니라 VS.NET 통합환경에서의 "웹 참조"까지도 가능합니다.

위의 "WcfConsole" 프로젝트의 App.Config에서 "IHelloWorld" 서비스에 대한 서비스 노출을 "http://localhost:9091/HelloService"에서 한다고 설정을 했으니, "웹 참조 주소" 창에는 당연히 그 주소를 넣으면 웹 참조를 통한 소스 생성이 가능합니다.

WSE 3.0 설정 대화창

3. "웹 참조"를 했으므로, 소스가 자동으로 생성되어지고 "Program.cs"에 다음과 같이 코드를 추가하면 됩니다.

    static void Main(string[] args)
    {
      MyService.CHelloWorld svc = new WcfConsumer.MyService.CHelloWorld();
      Console.WriteLine(svc.HelloWorld());
    }



첨부된 압축 파일을 해제하면 다음과 같은 예제 프로젝트들이 들어 있습니다.

WSE 3.0 설정 대화창





[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/22/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2006-11-07 06시48분
[정준명] 오, 다이어그램 직접 그리신건가요? 너무나 미려한데요 ^^;
[guest]
2006-11-07 09시00분
설마 제가 이런 그림을... ^^; Visual Studio Team System에서 제공되는 배포 다이어그램에서 제공되는 다이어그램들입니다. 그냥 이런 식으로 표현할 때 쓰는 것도 좋겠다는 생각이 들어서 적용해 보았습니다. ^^
kevin25
2007-03-21 11시49분
[초보] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 가 무슨 의미인지 아시는지요... 무조건 쓰는건지... 이게 무엇을 하는 역할인지 알려주실 수 있으신지요..^^ 좋은 하루 되세요.
[guest]
2007-03-22 12시16분
딱히 적절한 표현을 찾기 위해 웹 검색을 해보니, "WS-I Basic Profile은 웹 서비스가 서로 호환되도록 하는 권장 사항이 들어 있는 사양입니다."라는 표현이 가장 쉬운 듯하군요. ^^ 만약 이를 벗어나게 되면 다른 플랫폼(대표적인 예를 들어 "자바")과의 상호 웹 서비스 호출에 대한 보장을 할 수 없습니다.

[참조] https://docs.microsoft.com/en-us/previous-versions/ms181876(v=vs.80)
kevin25

... 61  62  63  64  65  66  67  68  69  70  71  72  [73]  74  75  ...
NoWriterDateCnt.TitleFile(s)
12112정성태1/12/202016830오류 유형: 589. PowerShell - 원격 Invoke-Command 실행 시 "WinRM cannot complete the operation" 오류 발생
12111정성태1/12/202020626디버깅 기술: 155. C# - KernelMemoryIO 드라이버를 이용해 실행 프로그램을 숨기는 방법(DKOM: Direct Kernel Object Modification) [16]파일 다운로드1
12110정성태1/11/202020021디버깅 기술: 154. Patch Guard로 인해 블루 스크린(BSOD)가 발생하는 사례 [5]파일 다운로드1
12109정성태1/10/202016705오류 유형: 588. Driver 프로젝트 빌드 오류 - Inf2Cat error -2: "Inf2Cat, signability test failed."
12108정성태1/10/202017521오류 유형: 587. Kernel Driver 시작 시 127(The specified procedure could not be found.) 오류 메시지 발생
12107정성태1/10/202018733.NET Framework: 877. C# - 프로세스의 모든 핸들을 열람 - 두 번째 이야기
12106정성태1/8/202019730VC++: 136. C++ - OSR Driver Loader와 같은 Legacy 커널 드라이버 설치 프로그램 제작 [1]
12105정성태1/8/202018216디버깅 기술: 153. C# - PEB를 조작해 로드된 DLL을 숨기는 방법
12104정성태1/7/202019473DDK: 9. 커널 메모리를 읽고 쓰는 NT Legacy driver와 C# 클라이언트 프로그램 [4]
12103정성태1/7/202022597DDK: 8. Visual Studio 2019 + WDK Legacy Driver 제작- Hello World 예제 [1]파일 다운로드2
12102정성태1/6/202018869디버깅 기술: 152. User 권한(Ring 3)의 프로그램에서 _ETHREAD 주소(및 커널 메모리를 읽을 수 있다면 _EPROCESS 주소) 구하는 방법
12101정성태1/5/202019245.NET Framework: 876. C# - PEB(Process Environment Block)를 통해 로드된 모듈 목록 열람
12100정성태1/3/202016673.NET Framework: 875. .NET 3.5 이하에서 IntPtr.Add 사용
12099정성태1/3/202019543디버깅 기술: 151. Windows 10 - Process Explorer로 확인한 Handle 정보를 windbg에서 조회 [1]
12098정성태1/2/202019314.NET Framework: 874. C# - 커널 구조체의 Offset 값을 하드 코딩하지 않고 사용하는 방법 [3]
12097정성태1/2/202017417디버깅 기술: 150. windbg - Wow64, x86, x64에서의 커널 구조체(예: TEB) 구조체 확인
12096정성태12/30/201919986디버깅 기술: 149. C# - DbgEng.dll을 이용한 간단한 디버거 제작 [1]
12095정성태12/27/201921733VC++: 135. C++ - string_view의 동작 방식
12094정성태12/26/201919437.NET Framework: 873. C# - 코드를 통해 PDB 심벌 파일 다운로드 방법
12093정성태12/26/201919060.NET Framework: 872. C# - 로딩된 Native DLL의 export 함수 목록 출력파일 다운로드1
12092정성태12/25/201917722디버깅 기술: 148. cdb.exe를 이용해 (ntdll.dll 등에 정의된) 커널 구조체 출력하는 방법
12091정성태12/25/201920134디버깅 기술: 147. pdb 파일을 다운로드하기 위한 symchk.exe 실행에 필요한 최소 파일 [1]
12090정성태12/24/201920178.NET Framework: 871. .NET AnyCPU로 빌드된 PE 헤더의 로딩 전/후 차이점 [1]파일 다운로드1
12089정성태12/23/201919113디버깅 기술: 146. gflags와 _CrtIsMemoryBlock을 이용한 Heap 메모리 손상 여부 체크
12088정성태12/23/201918094Linux: 28. Linux - 윈도우의 "Run as different user" 기능을 shell에서 실행하는 방법
12087정성태12/21/201918566디버깅 기술: 145. windbg/sos - Dictionary의 entries 배열 내용을 모두 덤프하는 방법 (do_hashtable.py) [1]
... 61  62  63  64  65  66  67  68  69  70  71  72  [73]  74  75  ...