Microsoft MVP성태의 닷넷 이야기
.NET Framework: 74.2. WCF로 구현하는 .NET Remoting [링크 복사], [링크+제목 복사],
조회: 27806
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
부모글 보이기/감추기
(연관된 글이 3개 있습니다.)
2. WCF로 구현하는 .NET Remoting


이번 토픽에서는 WCF의 Remoting 모드에 대해서 알아보겠습니다. 사실 "remoting 모드"라는 것은 제가 의미상으로 만들어낸 말일 뿐, 이런 용어는 없습니다. 그렇다면 왜 그런 용어를 제가 굳이 언급하는 것일까요?

원격 호출 방식은 크게 2가지로 나뉠 수 있습니다. 하나는 "웹 서비스 방식", 또 하나는 ".NET 리모팅 방식"이 그것입니다. 이 2가지는 절대 화합할 수 없을 것만 같습니다. 뭐랄까... 마치 "상대성 이론"과 "양자역학"의 관계라고나 할까요? (아마도 대통일장 이론이 나올때 쯤이면, 웹 서비스와 리모팅도 단일화될 것입니다.) 2가지 모두 나름대로의 뚜렷한 성격을 가지고 있기 때문인데요. 잘 아시는 것처럼 "웹 서비스"로 통신을 하게 되면 범용적으로 모든 프로세스들이 그 서비스를 이용할 수는 있지만 부가적인 Payload로 인해 통신이 가볍게 되지는 않습니다. 따라서 ".NET"과 ".NET" 간의 통신이라면 굳이 "웹 서비스 통신" 방식을 쓰지 않고 가볍고 최적화된 ".NET 리모팅 방식"을 같이 제공해 주게 되는 것입니다.
그런 이유로, 제가 설명을 무난하게 하기 위해서 굳이 "웹 서비스 모드"와 "Remoting 모드"라는 말로 나눠서 이야기할 것입니다.

우선, "웹 서비스 모드"는 지난번에 잠깐 살펴봤습니다. 어떻게 만드는지도 예제를 만들어 봤지요. 아직 안 읽어 보셨다면 아래의 링크를 참조하십시오.

3.1 WCF와 WSE 3.0의 활용
; https://www.sysnet.pe.kr/2/0/378

일단은 웹 서비스 모드는 그것으로 끝내고, 이번 회에서는 리모팅 모드에 대해서만 알아보도록 하겠습니다.



실제로 예제를 제작해 보면서 설명을 할 텐데요. 사실 app.config 및 자동 생성 코드를 제외하고는 위에서 링크를 걸어두었던 "3.1 WCF와 WSE 3.0의 활용"에서와 소스는 거의 비슷합니다.

[서버 측 WCF 제작]

1. 콘솔 응용 프로그램으로 서버 예제를 만들어 보겠습니다. 따라서 콘솔 프로젝트를 생성하는데, 여기서는 "WcfRemoteServer"라는 이름으로 생성하겠습니다.

2. "System.ServiceModel"에 대해 참조를 추가하고, "Program.cs"에 다음과 같이 입력합니다. (이전에 살펴본 웹 서비스로 하는 예제와 동일한 코드입니다.)

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace WcfRemoteServer
{
  class Program
  {
    static void Main(string[] args)
    {
      using (ServiceHost serviceHost = new ServiceHost(typeof(CHelloWorld)))
      {
        serviceHost.Open();

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

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

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

3. "새 항목 추가"를 통해서 "Application Configuration File" - app.config - 파일을 추가하고 다음과 같이 내용을 입력합니다.

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

  <system.serviceModel>

    <services>
      <service 
         name="WcfRemoteServer.CHelloWorld"
         behaviorConfiguration="HelloWorldBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9091/HelloService"/>
          </baseAddresses>
        </host>
        <endpoint address="net.tcp://localhost:9092/HelloService"
           binding="netTcpBinding"
           bindingConfiguration="HelloService_TcpBinding" 
           contract="WcfRemoteServer.IHelloWorld" />

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

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

    <bindings>
      <netTcpBinding>
        <binding name="HelloService_TcpBinding">
          <reliableSession enabled="false" ordered="true"/>
          <security mode="None" >
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

  </system.serviceModel>
  
</configuration>

4. 마지막으로 빌드를 정상적으로 완료하면 서버 측 WCF 서비스는 완성된 것입니다.




클라이언트 측 제작 단계는, 이전의 웹 서비스 예제보다 다소 복잡합니다. 왜냐하면, 이제는 "웹 참조 추가" 대화창을 통한 서비스 사용 코드를 생성할 수 없기 때문입니다. 대신, Windows SDK를 설치하면 "svcutil.exe"라는 도구를 "C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin" 폴더에서 볼 수 있는데, 이 유틸리티를 이용해서 서비스 호출 코드를 생성할 수 있게 됩니다. 만약 자신의 PC에 Windows SDK가 설치되어져 있지 않다면 다음의 경로에서 다운로드 받아 설치합니다.

Microsoft® Windows® Software Development Kit (ISO) for September CTP of Windows Vista and .NET Framework 3.0 Runtime Components
; http://www.microsoft.com/downloads/details.aspx?FamilyId=28FAD42D-983E-4A57-B5A6-BF058766A9FF&displaylang=en

용량이 1GB가 넘는데, 만약 여의치 않은 상황이라면 동료중에서 Windows SDK를 설치한 이가 있다면, 그에게서 "svcutil.exe"만 복사받으셔도 무방합니다.

준비가 되었다면 시작해 볼까요? ^^

1. 서비스를 호출하는 콘솔 프로젝트를 새로 생성합니다. 여기서는 "WcfRemoteClient"라고 이름 짓겠습니다.

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

3. 자, 이제 서비스 호출 코드를 자동 생성해야 할 텐데요. 서버 콘솔 프로그램(WcfRemoteServer.exe)을 실행시키고 다음과 같이 해서 소스 생성을 합니다.

C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin>svcutil http://localhost:9091/HelloService
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.3]
Copyright (c) Microsoft Corporation.  All rights reserved.

Attempting to download metadata from 'http://localhost:9091/HelloService' using
WS-Metadata Exchange or DISCO.
Generating files...
D:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\CHelloWorld.cs
D:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\output.config

4. 위의 과정을 통해서, CHelloWorld.cs 파일과 output.config 파일이 생성되었는데, CHelloWorld.cs 파일은 WcfRemoteClient 프로젝트에 추가시키고, output.config 파일의 내용은 복사해서 "App.config" 파일에 붙여 넣습니다.

5. 마지막으로, 다음과 같이 Main 함수를 작성하고 컴파일합니다.

    static void Main(string[] args)
    {
      HelloWorldClient hwc = new HelloWorldClient();
      Console.WriteLine(hwc.HelloWorld());
    }

[첨부된 압축 파일 "ConsoleHostService.zip"은 위의 예제를 포함하고 있습니다.]



위와 같이 만들고 나서, WcfRemoteServer.exe와 WcfRemoteClient.exe를 실행시키면 실제 동작되는 것을 확인할 수 있습니다. 아래의 내용은 동일한 HelloWorld 서비스 클래스에 대해 웹 서비스와 리모팅으로 호출한 패킷 내용을 비교한 것입니다. 잠깐만 보셔도... 역시 WcfRemoteServer/WcfRemoteClient 간의 호출이 간결하다는 것을 알 수 있습니다.

"웹 서비스 모드" 에서의 hello world 패킷 통신(실제 패킷에서 보기좋게 들여쓰기 한 것입니다.)

-- 요청 1 --
POST /HelloService HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.42)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.wcftest.com/IHelloWorld/HelloWorld"
Host: sedona2:9091
Content-Length: 292
Expect: 100-continue
Connection: Keep-Alive

-- 응답 1 --
HTTP/1.1 100 Continue

-- 요청 2 --
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
	<HelloWorld xmlns="http://www.wcftest.com/" /></soap:Body>
</soap:Envelope>

-- 응답 2 --
HTTP/1.1 200 OK
Content-Length: 215
Content-Type: text/xml; charset=utf-8
Server: Microsoft-HTTPAPI/1.0
Date: Wed, 18 Oct 2006 01:02:01 GMT

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
	<HelloWorldResponse xmlns="http://www.wcftest.com/">
		<HelloWorldResult>Hello World</HelloWorldResult>
	</HelloWorldResponse>
</s:Body>
</s:Envelope>




"리모팅 서비스 모드"에서의 hello world 패킷 통신

-- 요청 1 --
......#net.tcp://sedona2:9092/HelloService...

-- 응답 1 --
.

-- 요청 2 --
...u-http://www.wcftest.com/IHelloWorld/HelloWorld
#net.tcp://sedona2:9092/HelloService.HelloWorld.http://www.wcftest.com
/V...s...a.V.D......D...RV....F.7"...g.D,D*...D.......V.B......

-- 응답 2 --
...r5http://www.wcftest.com/IHelloWorld/HelloWorldResponse.HelloWorldResponse.
http://www.wcftest.com/.HelloWorldResultV.
..s...a.V.D......D...RV....F.7"...g.D.......V.B...B...Hello World...







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

[연관 글]






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

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

비밀번호

댓글 작성자
 



2006-10-19 08시08분
'대통일장 이론' 비유가 압권입니다. 하하하~ ^_^
songgun
2006-10-19 11시28분
^^
kevin25
2006-10-20 01시16분
위에서 종단점주소와 client간의 패킷을 잡기 위한 좋은 간편한 툴좀 소개 해주세요..^^
unbinara
2006-10-20 10시41분
개인적으로 만들어서 사용하고 있는 툴이 있긴 한데, 버그가 많아서 ^^; 저만 사용하고 있습니다. 일일이 설명하기도 귀찮고, 그다지 UI도 좋지 않아서요. 다른 분들은 Fiddler를 많이 이용하는 것으로 알고 있습니다. HTTP가 아닌 좀 더 low-level 수준으로 하는 경우에는 Windows Server 계열에 설치할 수 있는 네트워크 모니터링이나 그 외에 공개된 네트워크 패킷 캡쳐 프로그램들이 있지요. ^^

나중에 한번 설명은 드리겠지만, WCF의 경우에는 자체적인 로그 기능도 있습니다. 그 로그를 보는 Viewer도 나름대로는 쓸만하고요.
kevin25

... 106  107  108  109  110  111  112  113  114  115  116  117  118  [119]  120  ...
NoWriterDateCnt.TitleFile(s)
10949정성태4/28/201619949.NET Framework: 575. SharedDomain과 JIT 컴파일파일 다운로드1
10948정성태4/28/201623911.NET Framework: 574. .NET - 눈으로 확인하는 SharedDomain의 동작 방식 [3]파일 다운로드1
10947정성태4/27/201621793.NET Framework: 573. .NET CLR4 보안 모델 - 4. CLR4 보안 모델에서의 조건부 APTCA 역할파일 다운로드1
10946정성태4/26/201624576VS.NET IDE: 106. Visual Studio 2015 확장 - INI 파일을 위한 사용자 정의 포맷 기능 (Syntax Highlighting)파일 다운로드1
10945정성태4/26/201618342오류 유형: 327. VSIX 프로젝트 빌드 시 The "VsTemplatePaths" task could not be loaded from the assembly 오류 발생
10944정성태4/22/201619566디버깅 기술: 80. windbg - 풀 덤프 파일로부터 텍스트 파일의 내용을 찾는 방법
10943정성태4/22/201624420디버깅 기술: 79. windbg - 풀 덤프 파일로부터 .NET DLL을 추출/저장하는 방법 [1]
10942정성태4/19/201619734디버깅 기술: 78. windbg 사례 - .NET 예외가 발생한 시점의 오류 분석 [1]
10941정성태4/19/201619646오류 유형: 326. Error MSB8020 - The build tools for v120_xp (Platform Toolset = 'v120_xp') cannot be found.
10940정성태4/18/201622942Windows: 116. 프로세스 풀 덤프 시간을 줄여 주는 Process Reflection [3]
10939정성태4/18/201623953.NET Framework: 572. .NET APM 비동기 호출의 Begin...과 End... 조합 [3]파일 다운로드1
10938정성태4/13/201623513오류 유형: 325. 파일 삭제 시 오류 - Error 0x80070091: The directory is not empty.
10937정성태4/13/201631698Windows: 115. UEFI 모드로 윈도우 10 설치 가능한 USB 디스크 만드는 방법
10936정성태4/8/201642450Windows: 114. 삼성 센스 크로노스 7 노트북의 운영체제를 USB 디스크로 새로 설치하는 방법 [3]
10935정성태4/7/201626719웹: 32. Edge에서 Google Docs 문서 편집 시 한영 전환키가 동작 안하는 문제
10934정성태4/5/201625410디버깅 기술: 77. windbg의 콜스택 함수 인자를 쉽게 확인하는 방법 [1]
10933정성태4/5/201631043.NET Framework: 571. C# - 스레드 선호도(Thread Affinity) 지정하는 방법 [8]파일 다운로드1
10932정성태4/4/201623328VC++: 96. C/C++ 식 평가 - printf("%d %d %d\n", a, a++, a);
10931정성태3/31/201623621개발 환경 구성: 283. Hyper-V 내에 구성한 Active Directory 환경의 시간 구성 방법 [3]
10930정성태3/30/201621583.NET Framework: 570. .NET 4.5부터 추가된 CLR Profiler의 실행 시 Rejit 기능
10929정성태3/29/201631681.NET Framework: 569. ServicePointManager.DefaultConnectionLimit의 역할파일 다운로드1
10928정성태3/28/201637386.NET Framework: 568. ODP.NET의 완전한 닷넷 버전 Oracle ODP.NET, Managed Driver [2]파일 다운로드1
10927정성태3/25/201626583.NET Framework: 567. System.Net.ServicePointManager의 DefaultConnectionLimit 속성 설명
10926정성태3/24/201626151.NET Framework: 566. openssl의 PKCS#1 PEM 개인키 파일을 .NET RSACryptoServiceProvider에서 사용하는 방법 [10]파일 다운로드1
10925정성태3/24/201620440.NET Framework: 565. C# - Rabin-Miller 소수 생성 방법을 이용하여 RSACryptoServiceProvider의 개인키를 직접 채워보자 - 두 번째 이야기파일 다운로드1
10924정성태3/22/201621124오류 유형: 324. Visual Studio에서 Azure 클라우드 서비스 생성 시 Failed to initialize the PowerShell host 에러 발생
... 106  107  108  109  110  111  112  113  114  115  116  117  118  [119]  120  ...