login register Sysop! about ME  
qrcode
    최초 작성일 :    2008년 11월 24일
  최종 수정일 :    2008년 11월 24일
  작성자 :    Loner
  편집자 :    Loner (유 경상)
  읽음수 :    64,243

강좌 목록으로 돌아가기

필자의 잡담~

오늘부터 약 7-8회에 걸쳐 연재될 유경상 수석님의 WCF 컬럼입니다.
이 내용은 2009년 초에 책으로도 출간될 예정이기도 합니다.
(그래서, 글 중간 중간에는 '이 책에서..'와 같은 단어가 등장합니다. 양해해 주세요~)

컬럼의 내용과 담겨있는 성의는 여러분이 충분히 만족하실 듯 합니다.
제가 읽었보았더니, 다른 WCF 서적보다 훨씬 이해하기가 쉽고 읽기 편했거든요(그래서 강좌로 올리자고 꼬셨죠!)
그럼, 얼마나 대단한지 한번 읽어볼까요?

무엇인가를 한 줄에 간략히 설명하는 것은 대단히 어려운 작업 중에 하나이다. 예를 들어, 닷넷 프레임워크가 무엇인지 간략하게 한 줄로 설명하라든가, WCF가 무엇인지 간략히 설명하라는 등등의 질문들이 대략 난감하게 만드는 어려운 질문들 중 하나일 것이다. 게다가 책의 첫 번째 장은 항상 그러하듯이 이 책에서 다룰 내용이 어떤 것이라는 것을 개략적으로 보여줘야 하고, 그것이 무엇이다라는 정의를 내려야 하기도 하기 때문에 항상 어렵기 마련이다. 그래서 주위에 유명한 필자들이 1장을 쓰기가 가장 어렵다고 하나 보다.

WCF는 XML 웹 서비스(Web Service) 기반의 차세대 서비스 통신 프레임워크이다. 이것이 필자가 가장 간단하게 내릴 수 있는 WCF의 정의이다. 이 정의를 이제부터 필자와 함께 이해해 나가도록 해보자. 긴 여정이 될 것이지만 최대한 독자들을 지루하지 않게 노력할 것을 약속하는 바이다.

이번 장에서는 WCF의 배경, 웹 서비스에 관련된 이론 등등을 모두 멀리 던져 버리고 WCF가 어떤 작업을 위한 것인지를 직관적으로 살펴볼 방법을 사용하도록 하겠다. WCF가 무엇에 쓰는 물건인지는 그 이름에서 대략 알 수 있을 것이다. 개발자라는 눈치 밥을 좀 먹었다 치면 WCF가 통신에 사용되는 것인지는 대충 감을 잡았을지라도 정말로 이것이 무엇을 위한 기술인지 가장 빠르게 이해하는 방법 중 하나는 예제 코드를 통해 WCF가 어떤 일을 하는지 살펴보는 것이 가장 효과적일 것이다. 물론 WCF의 작동 방식을 그림으로 표현하고 이것을 이해하는 것이 개념을 잡는데 좀 더 빠를 수도 있지만, 이러한 그림과 더불어 간단한(?) 예제 코드를 살펴보는 것이 개발자를 위하는데 가장 효과적이라고 할 수 있기 때문이다.

그래서 필자는 이 장에서 Kernighan과 Ritchie가 저술한 "The C Programming Language" 이란 책의 기법을 써먹기로 했다. 그렇다. 바로 그 유명한 Hello world 예제를 통해 독자들이 WCF가 무엇이고 어떤 곳에 써먹는 기술인가에 대한 감을 잡도록 할 계획이다. 다음은 Kernighan과 Ritchie 의 Hello world 프로그램이다 .

Kernighan과 Ritchie는 C 언어를 창시한 사람으로써 “The C Programming Language” 란 책을 통해 전세계의 개발자들에게 알려진 유명한 엔지니어이다.

#include

main()
{
    printf("hello, world\n");
}

우리가 이제부터 살펴볼 WCF의 Hello world는 이것 보다 훨씬 더 복잡한 예제임은 틀림이 없다. 하지만 WCF 예제로서는 초 간단 예제를 살펴봄으로써 WCF에 대한 감을 잡을 수 있으리라 감히 생각하는 바이다.

WCF 걸음마

WCF는 웹 서비스 기반의 통신 프레임워크이다. 따라서 서로 통신하고자 하는 두 프로그램이 WCF를 이용하여 통신을 할 수 있다는 얘기가 되겠다. 이때, 어떤 기능(functionality)을 제공하는 프로그램으로서 호출을 받는 피호출자(callee)를 서비스(service)라 하고 기능을 제공 받기 위해 호출을 수행하는 호출자(caller)를 클라이언트라고 한다. 대개 클라이언트/서버란 용어는 많이 들어 봤겠지만 WCF와 같은 메시징 프레임워크에서는 서버란 용어보다는 서비스란 용어를 더 선호한다.

[그림 1]은 WCF를 통해 클라이언트와 서비스가 통신하는 모습을 보여주고 있다. WCF는 클라이언트와 서비스 사이에서 상호 작용하며 둘 사이의 통신을 보다 쉽고 강력하게 해주는 역할을 하게 된다. 그리고 클라이언트와 서비스는 XML 메시지를 주고 받음으로써 클라이언트가 서비스에게 기능적인 요청을 수행하고 서비스가 그 결과를 클라이언트에게 반환해 주는 것이다 . WCF를 메시징 프레임워크라고 부르는 것도 클라이언트와 서비스가 XML 메시지를 주고 받는데 사용되는 통신 프레임워크이기 때문이다.

WCF와 같은 서비스에서는 XML 기반의 SOAP(Simple Object Access Protocol) 메시지를 주고 받음으로써 원격 호출을 수행한다. 실제로 WCF는 SOAP 메시지뿐만 아니라 POX(Plain Old XML)이나 JSON(JavaScript Object Notation)과 같은 REST(Representational State Transfer) 스타일의 메시지를 주고 받을 수 있다. 하지만 당분간은 SOAP 메시지를 주고 받는다고만 이해해 두도록 하자. SOAP 메시지에 대해서는 2장에서 상세히 설명할 것이며 POX, JSON 스타일의 메시지는 부록 B에서 상세히 설명할 것이다. 따라서 이 책에서는 부록 B를 제외하고는 암시적으로 서비스와 클라이언트는 SOAP 메시지를 주고 받는다고 가정할 것이다.

그림 1. WCF 클라이언트와 서비스 그리고 WCF의 관계

Contract, Address, Binding의 개념

WCF 서비스는 다양한 WCF의 구성요소들에 의해 구축된다. 그들 중 가장 핵심적인 세가지는 주소(address), 계약(contract), 바인딩(binding) 이다. 이 세가지 요소는 WCF 프로그래밍의 가장 기초적인 개념으로 "WCF의 ABC" 라고도 불리기도 한다. WCF 에서 서비스의 주소(address)란 개념은 상당히 쉬운 개념들 중 하나로서 인터넷 상에서 서비스의 위치를 나타내는 URI를 말한다. 클라이언트가 서비스를 호출하기 위해서는 서비스가 도대체 어디 있는지 알아야 메시지를 전송할 것이 아닌가? 따라서 서비스를 호출하기 위해 사용하는, 즉 우리가 일반적으로 말하는 인터넷 주소가 바로 WCF의 주소가 되겠다. WCF의 주소는 곧 이어 설명할 바인딩(binding)이 어떤 프로토콜을 사용하는가에 따라 그 모양새가 조금씩 차이가 날 수 있음에 유의하자. 다음은 WCF의 주소의 예제들이다.

http://www.contoso.com/wcf/testservice.svc
https://www.simpleisbest.net/wcf/postinfo
net.tcp://appserver:2100/data/stockinfo.svc
net.pipe://localhost/LocalPipe
net.msmq://server/AsyncService

계약이란 WCF 서비스가 제공하는 기능(functionality) 들에 대한 인터페이스를 말한다. 한글화된 용어가 이해를 방해하는 듯한 느낌을 강하게 받지만 Contract 이란 단어를 마땅히 계약 이란 단어로 밖에 해석할 수 밖에 없어 안타깝기 그지 없다.

웹 서비스란 SOAP 프로토콜을 사용하여 어떤 기능을 제공하는 것을 말한다. 여기서 말하는 기능들이 곧 서비스(날씨 정보 서비스, 증권 정보 서비스 등)가 되며 HTTP 프로토콜과 XML 메시지(SOAP)를 통해 서비스를 제공 하기 때문에 웹 서비스란 용어를 사용하는 것이다.

그래도 '계약'이란 용어는 나중에 등장할 몇몇 난감한 단어들에 대한 번역들에 비하면 양반인 편이다. 어찌 되었건 서비스의 계약이란 쉽게 말해 서비스에 대한 인터페이스를 말하며, 이 인터페이스는 서비스가 어떤 기능을 제공하고 각 기능의 매개변수가 어떠한지를 기술한다. 보다 직접적으로 이야기 하자면 WCF에서 계약이란 WCF 서비스가 제공하는 메쏘드(method)들 무엇이며 이들 메쏘드가 어떤 타입의 매개변수를 취하고 그 반환 타입이 무엇인지를 기술하는 인터페이스를 말한다. 계약은 웹 서비스 동네에서 사용하는 용어라고 생각할 수 있으며 WCF의 계약은 닷넷 환경에서 인터페이스(interface) 타입과 일대일로 대응된다고 생각하면 보다 이해가 편할 것이다. 다음 코드 조각은 WCF에서 사용될 수 있는 전형적인 계약의 예가 되겠다.

public interface IBankingContract
{
    decimal Deposit(string account_id, decimal amount);
}

WCF의 바인딩(binding)은 WCF 서비스를 네트워크를 통해 호출할 때 고려해야 할 다양한 요소들의 집합으로써 설명할 수 있다. 일반적으로 네트워크 통신을 할 때 고려해야 할 사항들을 생각해 보면 다음과 같다.

  1. 어떤 프로토콜을 사용할 것인가?
  2. 예) TCP, HTTP, FTP, 등
  3. 데이터 포맷은 어떤 방식을 사용할 것인가?
  4. 예) 바이너리, 텍스트, MIME 등
  5. 네트워킹 보안을 적용할 것인가? 적용한다면 어떤 보안 방식을 취할 것인가?
  6. 예) SSL, 암호화 등
  7. 트랜잭션 처리, 비동기 전송 등의 진보된 기능을 사용할 것인가?

단순한 Socket 통신을 하더라도 이렇게 네트워크 통신에 고려할 사항들이 있기 마련인데, WCF 역시 XML 메시지를 전송할 때 어떤 프로토콜을 사용할지, 데이터 포맷을 어떻게 해야 할지, 보안을 적용할 것인지에 대한 여부를 결정해야 할 것이다. 이렇게 통신에 필요한 다양한 요소들을 정의할 수 있는 것이 WCF 바인딩 이며 WCF 바인딩은 HTTP, TCP, 명명된 파이프, MSMQ, P2P 등의 다양한 프로토콜 중 하나를 사용하면서 인터넷 보안 표준, 바이너리/텍스트의 메시지 인코딩 등의 네트워킹에 필요한 요소를 켜거나 끌 수 있다(enable/disable). 바인딩이란 용어가 처음에는 다소 혼동 될 수 있겠지만 WCF를 이해하고 WCF 응용 프로그램을 만들기 위해 가장 잘 이해하고 조작을 잘 해야 할 것이 바인딩이기 때문에 독자들은 좀 더 신경을 써야 할 것이 바로 바인딩인 것이다. 조금 후에 구체적인 코드 예제를 살펴본 후에 바인딩에 대해 조금 더 이야기 하도록 하자. 지금 이해가 잘 안되더라도 걱정할 필요가 없으며 조금도 성급해 할 필요도 없다. 수백 페이지나 되는 책에서 이제 겨우 몇 페이지를 넘겼을 뿐이다.

Endpoint 의 개념

WCF 서비스의 핵심적인 요소는 주소, 계약, 바인딩이라 하였다. WCF에서는 이들 세 가지 요소를 모두 합쳐서 서비스의 종점(endpoint)이라 부르며 WCF 서비스는 반드시 하나 이상의 종점을 갖는다. WCF에서는 클라이언트는 반드시 서비스의 종점을 통해서만 서비스를 호출할 수 있으므로 서비스의 종점을 서비스에 대한 관문 혹은 액세스 포인트 정도로 생각할 수도 있겠다. 실제로 WCF 클라이언트가 WCF 서비스를 호출하기 위해서는 서비스에 대한 종점 객체를 생성해야만 하며, 이 종점 객체는 서비스의 인터넷 주소가 무엇인지, 어떤 바인딩 구성을 사용하는지, 서비스의 계약은 어떠한 가를 모두 명시해야만 한다.

서비스가 하나의 이상의 종점을 갖는다는 말은 곧 WCF 서비스가 2개 이상의 종점을 가질 수 있다는 말이 되겠다. 실제로 하나의 서비스가 HTTP 기반의 바인딩과 TCP 기반의 바인딩을 각각 사용하는 2개의 종점을 가질 수 있으며, HTTP 프로토콜을 사용하는 클라이언트는 HTTP 기반의 종점을 통해서 서비스를 호출하고, TCP 프로토콜을 사용하는 클라이언트는 TCP 기반의 종점을 통해서 서비스를 호출할 수 있다는 것이다. 이점이 WCF의 장점 중 하나이다.

실 예로서, 어떤 WCF 서비스를 구현해 놓고 인터넷 상의 클라이언트는 상호운영성(interoperability)이 뛰어난 HTTP 기반의 바인딩을 사용하도록 하고, 인트라넷 상의 클라이언트는 성능적으로 보다 우수한 TCP 기반의 바인딩을 사용하도록 할 수 있다. 이 때, WCF 서비스가 어떤 바인딩을 사용하는가에 따라 서비스의 구현 코드가 달라지거나 구현 방식을 다르게 할 필요가 없으며 한번의 서비스 구현에 여러 바인딩을 동시에 적용하여 상호운영적인 측면이나 성능적인 측면, 보안적인 측면을 강조하는 여러 종점을 한번에 노출할 수도 있다는 것이다. 서비스가 복수개의 종점을 제공할 수 있다는 점은 이전의 닷넷 기반 통신 기술들인 ASP.NET 웹 서비스(ASMX), 닷넷 리모팅, COM+이 따라올 수 없는 WCF만의 독특하고 유연한 장점이라 말할 수 있겠다. 잠시 후에 실제로 여러 종점을 제공하는 예제코드를 다루어 볼 것이므로 이 부분에 대해서도 조금만 참도록 하자.

[그림 2]는 하나의 WCF 서비스가 2개 이상의 종점을 갖는 경우를 보여주고 있다. 아직 WCF에 대한 세부 사항이 언급되지 않았기 때문에 단순하게 표현되고 있지만, 이 책에서 [그림 2]와 비슷한 그림이 새로운 WCF의 개념이 등장할 때마다 보다 상세하게 표현이 되게 될 것이다.

그림 2. Contract, Address, Binding 그리고 EndPoint

서비스 호스트와 클라이언트

WCF를 이용하여 서비스를 구현하면, 이 서비스는 WCF 호스트(host)에 의해 호스팅이 되어야만 클라이언트의 호출을 받을 수 있게 된다. WCF는 서비스가 실제로 클라이언트 호출을 받을 수 있도록 호스팅 환경을 완벽하게 갖추고 있으며, 이 호스팅 환경은 일반 닷넷 EXE 어플리케이션 혹은 IIS를 이용하여 호스팅 될 수 있다. WCF가 제공하는 호스트는 다중 쓰레드 풀(multi-thread pool)을 완벽하게 지원하기 때문에 개발자가 여러 클라이언트의 동시 호출(concurrent call)에 대해 고민하거나 염려할 필요가 전혀 없다. 개발자는 단순히 호스트 객체(ServiceHost 클래스)를 생성하고 Open 메쏘드를 호출하기만 하면 된다. WCF 런타임이 네트워크 포트(port)나 HTTP 프로토콜을 구성하여 클라이언트 메시지를 수신하기 시작할 것이고 수신된 클라이언트 호출은 쓰레드 풀의 쓰레드 중 한 쓰레드에 의해 WCF 서비스가 호출될 것이다.

클래스, 타입, 객체

클래스, 타입, 객체 등의 용어는 항상 혼동을 일으키기 쉬운 용어이다. 개발자에게 가장 익숙하게 여기는 용어가 클래스로써 데이터(필드)와 행동(메쏘드)을 하나의 데이터 구조로 합쳐 놓은 것이 클래스이다. 이 책이 프로그래밍 언어 도입서가 아니기 때문에 클래스에 대해 상세히 설명하지는 않겠지만, 닷넷에서 클래스 외에도 구조체(structure), 열거형(enumeration), 위임자(delegate) 등의 다양한 데이터 타입들이 존재한다. 다양한 이들 데이터 타입을 통틀어 타입(type)이라고 지칭하곤 한다. 이 책에서는 어떤 타입의 구체적으로 "클래스"나 "구조체", "열거형" 등의 타입 종류를 명명할 것이다.

또 이 책에서는 "XXXX 객체"라는 용어를 많이 사용할 것이다. 이 용어의 정확한 표현은 XXXX 타입의 인스턴스 객체라는 의미이다. 보다 간결하고 명확한 의미 전달을 위해 간략하게 "XXXX 객체"라고 줄여서 표현하더라도 독자들은 혼동이 없길 바란다. 예를 들어 "XXXX 객체의 YYYY 속성" 이라고 표현되었다면 "XXXX 타입의 인스턴스가 제공하는 YYYY 속성" 이라는 의미이다.

WCF 클라이언트가 서비스를 호출하는 것 역시 많은 부분 WCF 프레임워크의 도움을 받게 된다. 클라이언트는 서비스의 계약으로부터 서비스가 어떤 메쏘드를 제공하며 그 메쏘드의 매개변수, 반환 값(return value)에 대한 정보를 얻을 수 있다. WCF 런타임과 유틸리티는 서비스의 계약 정보로부터 서비스에 대한 프록시(proxy) 클래스를 생성할 수 있으며, 이 프록시 클래스는 웹 서비스 호출을 마치 로컬 메쏘드 호출과도 같이 간단한 작업으로 만들어 줄 수 있게 된다.

WCF 클라이언트가 프록시를 생성하는 작업 외에 추가적으로 수행해야 할 것은, WCF 런타임이 적절히 서비스를 찾고 XML 메시지를 전송할 수 있도록 호출하고자 하는 서비스의 종점에 대한 정보를 제공하는 것이다. 다시 말해 서비스에 대해 어떤 주소와 어떤 바인딩을 사용해야 하는가를 WCF 런타임에게 알려주어야 하는 것이다. 정확한 주소가 있어야만 해당 서비스에게 메시지가 전달될 것이고, 메시지를 전달할 프로토콜, 보안 사용 여부 등이 서비스가 이해할 수 있는 것이어야 하므로 서비스가 제공하는 바인딩과 동일한 바인딩을 클라이언트가 사용해야 함은 눈치로도 알 수 있을 것이다.

[그림 3]은 서비스 프록시와 서비스 호스트의 작동 방식을 간략하게 보여주고 있다. 클라이언트는 서비스 프록시를 통해 서비스를 호출하게 되며 프록시는 WCF 런타임을 통해 닷넷 메쏘드 호출을 XML 메시지로 바꾸어 준다. 한편, 서비스 호스트에 의해 호스팅 된 서비스는 서비스의 바인딩이 지정하는 네트워크 프로토콜의 리스너(listener)를 구동하여 XML 메시지를 수신한다. 리스너는 수신된 XML 메시지를 서비스 디스패처(dispatcher)에게 전달하고 디스패처는 메시지의 내용을 해석하여 적절한 서비스의 메쏘드를 호출하게 된다. 이러한 작업은 서비스 호스트, 보다 정확하게 말해 WCF 런타임이 제공하는 쓰레드 풀의 한 쓰레드를 이용하게 되므로 동시에 여러 클라이언트가 서비스를 호출하더라도 동시 액세스(concurrent access)가 가능하다.

그림 3. 서비스 프록시와 서비스 호스트

[그림 3]에서 등장하는 리스너나 디스패처, 그리고 쓰레드 풀에 대해서는 독자들은 걱정할 필요가 없다. 이들은 모두 WCF 런타임에 의해 제공되는 기능으로써 개발자가 이들에 대해 코드를 작성하거나 구현을 해야 할 것은 거의 없다. 개발자는 단순히 서비스를 정의하고 구현한 후에 이것을 서비스 호스트를 통해 구동시키기만 하면 된다.


authored by

  GoodLookie
  2008-11-24(11:25)
캐릭 이미지
잘봤습니다..^^
이해하기 쉽게 되어있네요^^

  hero100
  2008-11-24(15:58)
캐릭 이미지
수고 많으셨습니다.
책이 하루 빨리 출판되길 바래요 ㅎㅎㅎ

  wind1379
  2008-11-25(09:00)
캐릭 이미지
살짝만 맛을 봐도 책 내용이 기대 됩니다...[Mr.NET!]
  aesop
  2008-11-25(10:59)
캐릭 이미지
우왕 ㅋ굳ㅋ. 기대 만빵.
  soha0706
  2009-01-17(10:14)
아직 잘 모르겠지만.. XMLRPC나 자바RMI의 개념과 비슷한건가요??
  hamtol
  2009-06-11(09:57)
좋은 강좌 잘 보고 있습니다. 감사합니다.
  saja0405
  2010-01-04(17:56)
잘 읽었습니다. 감사합니다.

 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})