<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MarinerERP.WebService.DataService.InsaServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <services>
    <service behaviorConfiguration="MarinerERP.WebService.DataService.InsaServiceBehavior"
      name="MarinerERP.WebService.DataService.InsaService">
        <endpoint address="" binding="netTcpBinding" contract="IMarinerChannel.IInsaModule" />
      <endpoint address="mex1" binding="mexTcpBinding" contract="IMetadataExchange" />
<!—접속할땐 net.tcp://localhost:28800/dataservice/insaService.svc/mex1 이런식이 된다 –>
      <endpoint binding="basicHttpBinding" bindingConfiguration="" contract="IMarinerChannel.IInsaModule" />
    </service>
  </services>
</system.serviceModel>

 

WCF(Windows Communication Foundation) 서비스를 프로그래밍할 때 서비스에 대한 메타데이터를 게시하는 것이 좋습니다. 예를 들어, 메타데이터는 서비스에 사용되는 모든 메서드와 데이터 형식을 설명하는 WSDL(웹 서비스 기술 언어) 문서일 수 있습니다. WCF 서비스에 대한 메타데이터를 반환하면 서비스 사용자가 서비스에 대한 클라이언트를 손쉽게 만들 수 있습니다. WCF 메타데이터 끝점에 대한 자세한 내용은 메타데이터를 참조하십시오.

WCF를 사용하여 구현된 서비스는 하나 이상의 메타데이터 끝점을 공개하여 메타데이터를 게시합니다. WCF의 메타데이터 끝점에는 다른 끝점과 마찬가지로 주소, 바인딩 및 계약이 있습니다. MetadataReference 인터페이스는 WCF의 모든 메타데이터 끝점에서 구현되는 서비스 계약을 지정합니다.

서비스 구현에서 MetadataReference 계약을 구현할 필요는 없습니다. 대신 서비스 설명에 ServiceMetadataBehavior를 추가합니다.

또한 구성을 사용하는 경우에는 끝점 요소의 contract 특성을 IMetadataExchange로 설정합니다. 예제를 보려면 방법: 구성 파일을 사용하여 서비스의 메타데이터 게시를 참조하십시오.

WCF에서 메타데이터를 게시하는 방법에 대한 자세한 내용은 메타데이터 게시를 참조하십시오.

 

net.tcp 프로토콜사용하기 세팅하기

net.tcp 프로토콜을 사용하고자 하는 웹사이트에 바인딩을 추가합니다.

 

그리고 웹서비스가 사용될 폴더를 응용프로그램으로 변환합니다.

 

 

이폴더안에는   웹서비스가 들어있습니다.

 

 

명령어로 NET.TCP 활성화하기

net.tcp프로토콜을 추가하는 명령어 하지만 위에서 수동으로 입력했기때문에 패스


%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='19001:*']


net.tcp프로토콜활성화명령
 
위의 이미지처럼  설정(http => http,net.tcp)해주면 아래처럼 명령어를 입력 할 필요가 없다

%windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http,net.tcp

"Default Web Site" <—웹사이트 이름

"Default Web Site/servicemodelsamples" / 웹사이트 아래에 응용프로그램으로 변환했던 폴더명

 

활성화된 프로토콜 제거

%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" --bindings.[protocol='net.tcp',bindingInformation='19001:*']

주의

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MarinerERP.WebService.DataService.InsaServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MarinerERP.WebService.DataService.InsaServiceBehavior"
        name="MarinerERP.WebService.DataService.InsaService">
            <endpoint address="" binding="netTcpBinding" contract="IMarinerChannel.IInsaModule" />
        <endpoint address="mexTcp" binding="mexTcpBinding" contract="IMetadataExchange" />


      </service>
    </services>
  </system.serviceModel>
</configuration>

<endpoint address="" binding="netTcpBinding" contract="IMarinerChannel.IInsaModule" />
<endpoint address="mexTcp" binding="mexTcpBinding" contract="IMetadataExchange" />

IMetadataExchange 을 꼭 생성해주자
URL 은

msdn

http://msdn.microsoft.com/ko-kr/library/ms752218.aspx

 

이 샘플은 WAS에 의해 활성화된 작업자 프로세스에서 호스팅되는 서비스 라이브러리(.dll) 및 클라이언트 콘솔 프로그램(.exe)으로 구성됩니다. 콘솔 창에는 클라이언트 동작이 표시됩니다.

이 서비스는 요청-회신 통신 패턴을 정의하는 계약을 구현합니다. 다음 샘플 코드와 같이 계약은 수학 작업(Add, Subtract, Multifly 및 Divide)을 노출시키는 ICalculator 인터페이스에 의해 정의됩니다.

TCP 포트 공유가 설정되고 보안이 해제된 net.tcp 바인딩 변형이 샘플에 사용됩니다. 보안된 TCP 바인딩을 사용하려면 서버의 보안 모드를 원하는 설정으로 변경하고 클라이언트에서 Svcutil.exe를 다시 실행하여 업데이트 클라이언트 구성 파일을 생성합니다.

다음 샘플에서는 서비스에 대한 구성을 보여 줍니다.

<system.serviceModel>

    <services>
      <service name="Microsoft.ServiceModel.Samples.CalculatorService"
               behaviorConfiguration="CalculatorServiceBehavior">
        <!-- This endpoint is exposed at the base address provided by host: net.tcp://localhost/servicemodelsamples/service.svc  -->
        <endpoint binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
          contract="Microsoft.ServiceModel.Samples.ICalculator" />
        <!-- the mex endpoint is explosed at net.tcp://localhost/servicemodelsamples/service.svc/mex -->
        <endpoint address="mex"
                  binding="mexTcpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="PortSharingBinding" portSharingEnabled="true">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>

    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

 

  • Windows Communication Foundation 샘플의 일회 설치 절차를 수행했는지 확인합니다.

    또한 HTTP가 아닌 WCF 활성화 구성 요소를 설치해야 합니다.

    1. 시작 메뉴에서 제어판을 선택합니다.
    2. 프로그램 및 기능을 선택합니다.
    3. Windows 구성 요소 사용/사용 안 함을 클릭합니다.
    4. Microsoft .NET Framework 3.0 노드를 확장하고 Windows Communication Foundation 비-HTTP 활성화 기능을 선택합니다.
  • TCP 활성화를 지원하도록 WAS를 구성합니다.

    편의를 위해 다음 두 단계는 샘플 디렉터리에 있는 AddNetTcpSiteBinding.cmd라는 배치 파일에서 구현됩니다.

    1. net.tcp 활성화를 지원하려면 기본 웹 사이트를 먼저 net.tcp 포트에 바인딩해야 합니다. IIS(인터넷 정보 서비스) 7.0 관리 도구 집합과 함께 설치되는 Appcmd.exe를 사용하여 이 작업을 수행할 수 있습니다. 관리자 수준 명령 프롬프트에서 다음 명령을 실행합니다.

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

      참고: 이 명령은 줄 바꿈 없이 한 줄로 입력해야 합니다. 이 명령은 임의의 호스트 이름을 사용하여 TCP 포트 808에서 수신 대기하는 기본 웹 사이트에 net.tcp 사이트 바인딩을 추가합니다.

    2. 사이트 내의 모든 응용 프로그램이 공통된 net.tcp 바인딩을 공유하지만 각 응용 프로그램에서는 개별적으로 net.tcp 지원을 사용하도록 설정할 수 있습니다. /servicemodelsamples 응용 프로그램에 대해 net.tcp를 사용하도록 설정하려면 관리자 수준 명령 프롬프트에서 다음 명령을 실행합니다.

      %windir%\system32\inetsrv\appcmd.exe set app
      "Default Web Site/servicemodelsamples" /enabledProtocols:http,net.tcp

    WCF Activation 구성 요소 설치 및 구성

    http://msdn.microsoft.com/ko-kr/library/ms789006.aspx

    이 항목에서는 Windows Vista에서 HTTP 네트워크 프로토콜을 통해 통신하지 않는 WCF(Windows Communication Foundation) 서비스를 호스팅하도록 WAS라고도 하는 Windows Process Activation Service를 설정하는 데 필요한 단계에 대해 설명합니다. 다음 단원에서는 이 구성 단계에 대해 간략히 설명합니다.

    • WCF 활성화 구성 요소를 설치하거나 설치를 확인합니다.
    • HTTP가 아닌 프로토콜을 지원하도록 WAS를 구성합니다. 다음 절차에서는 TCP 활성화를 위해 Windows Vista를 구성합니다.

    Windows Vista에서 WAS를 설치 및 구성한 후에 방법: WAS에서 WCF 서비스 호스팅의 절차를 참조하여 WAS를 사용하고, HTTP가 아닌 끝점을 노출하는 WCF 서비스를 만드십시오.

    WCF Non-HTTP Activation 구성 요소를 설치하려면

    1. 시작 단추를 클릭한 다음 제어판을 클릭합니다.

    2. 프로그램을 클릭하고 프로그램 및 기능을 클릭합니다.

    3. 작업 메뉴에서 Windows 기능 사용/사용 안 함을 클릭합니다.

    4. .NET Framework 3.0 노드를 찾아서 선택한 다음 확장합니다.

    5. WCF Non-HTTP Activation 구성 요소 상자를 선택하고 설정을 저장합니다.

    TCP 활성화를 지원하도록 WAS를 구성하려면

    1. net.tcp 활성화를 지원하려면 먼저 기본 웹 사이트를 net.tcp 포트에 바인딩해야 합니다. 이 작업은 IIS 7.0 관리 도구 집합과 함께 설치되는 Appcmd.exe를 사용하여 수행할 수 있습니다. 관리자 수준 명령 프롬프트 창에서 다음 명령을 실행합니다.

    %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

    net.tcp 사이트 바인딩을 제거하려면

    1. net.tcp 사이트 바인딩을 제거하려면 관리자 수준 명령 프롬프트 창에서 다음 명령을 실행합니다.

    %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -bindings.[protocol='net.tcp',bindingInformation='808:*']

     

     

     

    http://msdn.microsoft.com/ko-kr/library/ms733109.aspx

    WAS에서 WCF 서비스 호스팅

    이 항목에서는 WAS(Windows Process Activation Service)에서 호스팅되는 WCF(Windows Communication Foundation) 서비스를 만드는 데 필요한 기본 단계에 대해 간략하게 설명합니다. WAS는 HTTP가 아닌 전송 프로토콜에서 작동하는 IIS(인터넷 정보 서비스) 기능을 일반화한 새 프로세스 활성화 서비스입니다. WCF는 수신기 어댑터 인터페이스를 사용하여 WCF에서 지원하는 HTTP가 아닌 프로토콜(예: TCP, 명명된 파이프 및 메시지 큐)을 통해 수신된 활성화 요청과 통신합니다.

    이 호스팅 옵션을 사용하려면 WAS 활성화 구성 요소를 적절히 설치하여 구성해야 하지만 호스팅 코드를 응용 프로그램의 일부로 작성하지 않아도 됩니다. WAS 설치 및 구성에 대한 자세한 내용은 방법: WCF Activation 구성 요소 설치 및 구성을 참조하십시오.

    WCF 서비스를 WAS에서 호스팅할 경우 일반적으로 표준 바인딩이 사용됩니다. 그러나 WAS에서 호스팅되는 서비스를 구성하기 위해 NetTcpBindingNetNamedPipeBinding을 사용하는 경우 제약 조건을 충족해야 합니다. 서로 다른 끝점이 동일한 전송을 사용하는 경우 바인딩 설정은 다음 7개의 속성과 일치해야 합니다.

     

     

     

     

     

    http://msdn.microsoft.com/ko-kr/magazine/cc163357.aspx

    WAS로 HTTP를 초월한 WCF 서비스 확장

    Dominick Baier and Christian Weyer and Steve Maine

    코드 다운로드 위치: WAS2007_09.exe (178 KB)
    Browse the Code Online

    이 기사는 Windows Server 2008 시험판 버전을 기준으로 합니다. 여기에 포함된 모든 정보는 변경될 수 있습니다.

    이 기사에서 다루는 내용:

    • IIS 6.0과 IIS 7.0의 아키텍처 및 프로세스 모델
    • IIS 6.0에서 웹 서비스가 호스팅되는 방법
    • IIS 7.0으로 견고한 WCF 서비스 호스팅
    • WAS(Windows Process Activation Service)의 작동 방식
    • HTTP 이외의 프로토콜 지원

    이 기사에서 사용하는 기술:
    IIS, WAS

      목차

    IIS 6.0 아키텍처와 프로세스 모델
    IIS 7.0과 WAS
    WAS의 내부
    구성과 다중 프로토콜 주소 지정
    수신기가 수신하는 방법
    HTTP 이외의 프로토콜을 통한 메시지 기반 활성화
    작업자 프로세스 초기화
    수신기에서 작업자로 데이터 이동
    WAS에 WCF 서비스 호스팅
    WAS에서 호스팅되는 서비스의 수명 관리
    WAS에서 호스팅되는 서비스의 자동 설정
    WAS 확장

    지난 수년간 계속 진행된 서비스 지향 응용 프로그램에 대한 활발한 논의를 통해 실제 프레임워크와 런타임을 비롯하여 서비스 지향 연결 시스템을 설계, 구축 및 배포하기 위한 도구 개발이 이루어졌습니다. 관리 코드로 서비스와 서비스 소비자를 작성할 수 있도록 해 주는 WCF(Windows® Communication Foundation)는 이러한 도구의 좋은 예입니다.

    콘솔 응용 프로그램, Windows Forms 응용 프로그램 또는 WPF(Windows Presentation Foundation) UI 응용 프로그램을 비롯하여 어떤 Windows 프로세스로도 WCF 기반 서비스를 호스팅할 수 있다는 것이 바로 WCF의 강력한 기능 중 하나입니다. 심지어 구성된 ID를 대신하여 백그라운드로 실행되는 장기 실행 Windows NT® 서비스에 WCF 서비스를 자체 호스팅할 수도 있습니다. HTTP 기반 끝점이 있는 WCF 서비스 또한 기존 웹 서비스가 ASP.NET과 ASMX에 의해 구현된 것과 비슷하게 IIS 내부에서 호스팅할 수 있습니다.

    IIS 7.0을 통해 견고한 WCF 서비스를 제공하려면 WAS(Windows Process Activation Service)라고 하는 IIS의 새로운 기능에 대한 이해가 필수적입니다. WAS는 HTTP를 초월하여 전체 IIS 패키지를 설치하지 않고도 WCF 서비스를 호스팅할 수 있도록 하는 IIS 7.0의 핵심적인 기본 구성 요소입니다.

    WAS에 대한 세부적인 내용과 이를 직접 응용 프로그램에 사용하는 방법을 배우기에 앞서 IIS 6.0의 호스팅이 작동하는 방식과 IIS 7.0의 새 프로세스가 더 유용한 이유를 확인해 보겠습니다.

    IIS 6.0 아키텍처와 프로세스 모델

    Windows Vista®와 Windows Server® 2008의 새로운 프로세스 활성화 메커니즘을 올바르게 이해하려면 IIS 6.0 아키텍처와 프로세스 모델에 익숙해질 필요가 있습니다. Windows Server 2003과 IIS 6.0의 아키텍처는 수신기 프로세스와 작업자 프로세스 집합이라는 두 가지 기본적인 부분으로 나누어집니다. IIS 6.0 수신기 프로세스는 Windows 서비스 제어 관리자에 의해 활성화되는 장기 실행 Windows NT 서비스인 w3svc 서비스에 구현됩니다. 수신기 프로세스는 HTTP를 통해 메시지가 도착하기를 기다린 다음, 이를 적절한 작업자 프로세스(w3wp.exe)로 발송합니다. 이 작업자 프로세스는 최종적으로 요청을 처리하는 응용 프로그램 코드를 호스팅합니다.

    네트워크에 도착한 요청은 커널 모드 HTTP 스택(http.sys)에 의해 처리되고 수신기 프로세스에 전달됩니다. 그러면 w3svc 프로세스는 요청 URI를 살펴본 다음, 이를 사용하여 특정 IIS 응용 프로그램 풀 내부에 있고 결과적으로 작업자 프로세스(w3wp) 인스턴스 내부에서 호스팅되는 특정 IIS 응용 프로그램에 요청을 매핑합니다(그림 1 참조). 요청 URI와 응용 프로그램 간의 매핑은 IIS 메타베이스에 저장된 구성 정보를 바탕으로 이루어지며, 이 정보는 %windir%\system32\inetsrv 폴더에 저장된 metabase.xml 및 mbschema.xml 파일에서 볼 수 있습니다. 대상 응용 프로그램을 확인한 w3svc는 몇 가지 내부 데이터 구조를 조사하여 대상 작업자 프로세스와 응용 프로그램 풀을 확인할 수 있습니다.

    그림 1 IIS 6.0 기본 아키텍처 (더 크게 보려면 이미지를 클릭하십시오.)

    이 시점에 대상 IIS 서버의 상태에 따라 두 가지 중 한 가지가 발생할 수 있습니다. 해당 풀에서 이전 요청을 수신하여 작업자 프로세스와 응용 프로그램 풀이 이미 실행 중인 경우에는 활성화가 필요 없습니다. 따라서 요청은 간단히 대기 중인 작업자 프로세스로 발송됩니다. 현재 요청을 처리하기 위한 작업자 프로세스가 없는 경우에는 수신기 프로세스가 새 w3wp 인스턴스를 만들고 요청을 발송해야 합니다.

    IIS 6.0 작업자 프로세스는 간단한 실행 파일입니다. 활성화 요청에 응답하여 시작된 다음에는 가장 먼저 관리되지 않는 간단한 shim DLL(w3wphost.dll)을 로드하여 w3svc가 작업자 프로세스와 통신할 수 있도록 합니다. shim은 또한 ASP.NET의 관리되는 구성 요소와 IIS의 관리되지 않는 구성 요소 간의 인터페이스를 구현하는 aspnet_isapi.dll을 로드하는 작업을 담당합니다.

    aspnet_isapi.dll은 CLR(공용 언어 런타임)을 작업자 프로세스로 로드하고 ASP.NET의 관리되는 호스팅 구성 요소가 있는 공간인 기본 응용 프로그램 도메인을 만드는 작업을 담당합니다. 이러한 관리되는 호스팅 구성 요소는 요청에 따라 IIS 응용 프로그램당 한 개씩 추가 응용 프로그램 도메인을 만들고 요청 URI에 따라 이 도메인으로 요청을 라우팅하는 작업을 담당합니다.

    IIS 7.0과 WAS

    IIS 6.0 프로세스 모델을 이해하고 있다면 IIS 7.0과 WAS도 이해할 수 있을 것입니다. 수신기, 작업자 및 응용 프로그램 관리자를 비롯한 IIS 6.0의 모든 주요 아키텍처 구성 요소는 WAS에서도 여전히 유지되고 있습니다. 차이점은 IIS 7.0과 WAS 구현은 HTTP 이외의 시나리오를 지원하므로 서비스 기반 응용 프로그램 아키텍처에서도 잘 작동할 수 있다는 것입니다.

    WAS의 관리 효율성, 신뢰성 및 확장성은 Windows Server 2003에서 ISS 6.0을 사용하던 때와 완전히 동일하게 제공됩니다. 그러나 이제는 IIS 6.0에서 HTTP 기반 응용 프로그램에만 제공되던 요청 시 활성화, 프로세스 상태 모니터링, 엔터프라이즈 수준 관리 효율성, 신속한 오류 방지와 같은 훌륭한 IIS 기능을 HTTP 기반이 아닌 응용 프로그램과 서비스에서도 사용할 수 있게 되었습니다.

    WAS의 내부

    IIS 6.0에서 w3svc 서비스는 두 가지 역할을 담당했습니다. http.sys에 등록되었기 때문에 HTTP 수신기 역할을 수행했으며 수신 HTTP 트래픽에 대한 직접 수신자이기도 했습니다. 또한 새 w3wp 인스턴스를 시작하고 적절하게 요청을 발송하는 프로세스 활성화 구성 요소를 소유하고 있었습니다. IIS 7.0에서 이러한 두 가지 책임은 별도의 Windows NT 서비스로 리팩터링되었습니다. w3svc 프로세스는 HTTP 수신기로서의 역할을 유지하지만 구성과 프로세스 활성화를 담당하는 구성 요소는 구성 관리자, 프로세스 관리자 및 관리되지 않는 수신기 어댑터 인터페이스라는 세 부분으로 구성된 WAS로 분리되었습니다.

    구성 관리자는 IIS 7.0에서 메타베이스를 대체하는 applicationhost.config에서 응용 프로그램 구성과 응용 프로그램 풀 구성을 읽습니다. 프로세스 관리자는 응용 프로그램 풀을 기존 작업자 프로세스에 매핑하며, 활성화 요청에 응답하여 새 응용 프로그램 풀을 호스팅할 새 w3wp 인스턴스를 시작하는 역할을 담당합니다. 관리되지 않는 수신기 어댑터 인터페이스는 외부 수신기가 수신하는 활성화 요청을 WAS에 전달하는 방법을 정의합니다.

    w3svc 서비스는 커널 수준 http.sys와의 통신을 소유하며 수신기 어댑터 인터페이스를 통해 HTTP 활성화 요청을 WAS에 전달합니다.

    WCF는 수신기 어댑터 인터페이스를 사용하여 TCP, 명명된 파이프 및 MSMQ를 비롯한 HTTP 이외의 지원 프로토콜을 통해 수신한 활성화 요청에 대한 통신을 수행합니다. HTTP가 아닌 프로토콜을 통해 실제로 요청을 수신하는 WCF 기능은 NetTcpPortSharing, NetTcpActivator, NetPipeActivator 및 NetMsmqActivator(그림 2 참조)의 네 가지 장기 실행 Windows NT 서비스를 호스팅하는 SMSvcHost.exe 내에서 호스팅됩니다.

    그림 2 IIS 7.0과 WAS의 기본 아키텍처 (더 크게 보려면 이미지를 클릭하십시오.)

    NetTcpPortSharing WCF TCP 포트 공유 서비스입니다. 중앙 TCP 수신기를 구현하여 여러 프로세스가 같은 TCP 포트를 수신할 수 있도록 합니다. 이 서비스는 IIS 7.0이 설치되어 있지 않아도 사용할 수 있습니다.

    NetTcpActivator WCF TCP 활성화 서비스이며, TCP 활성화 요청을 WAS에 전달합니다.

    NetPipeActivator WCF 명명 파이프 활성화 서비스이며, 명명된 파이프 활성화 요청을 WAS에 전달합니다.

    NetMsmqActivator WCF MSMQ 활성화 서비스이며, MSMQ 활성화 요청을 WAS에 전달합니다.

    이러한 서비스는 같은 이진 파일에 있지만 별개의 Windows NT 서비스이므로 공격 취약점이나 오버헤드를 줄이기 위해 개별적으로 중지 또는 시작할 수 있습니다. 이들은 모두 수신기 서비스의 예이며 비슷한 방법으로 작동합니다. 따라서 여기에서는 TCP 활성화에 초점을 맞추겠습니다. TCP 활성화는 명명된 파이프 및 MSMQ의 예로도 활용할 수 있습니다. 각각의 경우 유일한 차이점은 사용되는 네트워크 리소스의 특정 유형뿐입니다.

    구성과 다중 프로토콜 주소 지정

    WAS를 활용하여 응용 프로그램을 활성화하려면 먼저 해당 응용 프로그램을 구성해야 합니다. WAS에서 호스팅되는 각 응용 프로그램의 해당 구성 항목은 %windir%\system32\inetsrv\config\applicationhost.config에 있습니다. 이 정보에는 응용 프로그램을 호스팅할 응용 프로그램 풀, 응용 프로그램을 고유하게 식별하는 URL 조각 등이 포함됩니다. 이에 대한 예는 조금 뒤에 살펴보겠습니다. IIS 6.0에서와 비슷하게 각 응용 프로그램은 응용 프로그램 풀 및 사이트와 연결됩니다. 각 사이트에는 지원하는 네트워크 프로토콜에 대한 주소 바인딩 집합이 있습니다. 예를 들어 관리자는 포트 80에 HTTP를 바인딩하고 포트 7777에 TCP를 바인딩하도록 기본 사이트를 구성할 수 있습니다. 이 사이트에서 각각 /Foo와 /Bar를 수신하는 응용 프로그램 두 개를 별도의 응용 프로그램 풀에서 호스팅한다고 가정해 보겠습니다. 이 구성에서 /Foo 응용 프로그램은 http://myserver.com/Foo와 net.tcp://myserver.com:2323/Foo에서 수신하며 /Bar 응용 프로그램은 http://myserver.com/Bar와 net.tcp://myserver.com:2323/Bar에서 수신합니다. 수신되는 방법에 관계없이 각 응용 프로그램 풀에는 자체 작업자 프로세스가 있으므로, 가령 /Foo에 대한 모든 요청이 작업자 프로세스 1로 간다면 /Bar에 대한 모든 요청은 작업자 프로세스 2로 가게 됩니다. 일반적으로 응용 프로그램의 사이트는 응용 프로그램과 연결되는 네트워크 주소 집합을 결정하며, 해당 응용 프로그램 풀은 이를 호스팅하는 작업자 프로세스 인스턴스를 결정합니다. 응용 프로그램 풀 한 개당 작업자 프로세스 한 개라는 규칙은 웹 가든을 사용하지 않는 경우에만 적용됩니다. 웹 가든을 사용하는 경우 각 응용 프로그램 풀은 자체 작업자 프로세스 집합에 매핑되며, 작업자 프로세스의 최대 개수는 응용 프로그램 풀의 구성에 지정됩니다.

    수신기가 수신하는 방법

    수신기는 메시지를 수신해야 하며 이를 위해 소켓 또는 파이프라인 핸들을 열거나 MSMQ 읽기를 시작하는 등의 작업이 필요합니다. 그러나 올바른 메시지를 수신하기 위해서는 WAS로부터 필요한 주소 지정 정보를 입수해야 합니다. 이 작업은 수신기 시작 중에 수행되는데, 프로토콜의 수신기 어댑터는 WAS 수신기 어댑터 인터페이스에 있는 함수를 호출하여 "현재 net.tcp 프로토콜에서 수신하고 있으니 지금 내가 전달하는 콜백 함수 집합을 사용하여 알아야 할 사항을 알려달라"라는 내용을 전달합니다. 이에 대한 응답으로 WAS는 해당 프로토콜을 통해 메시지를 받도록 구성된 응용 프로그램을 위한 모든 구성을 사용해 콜백을 수행합니다. 예를 들어 위의 예에서 TCP 수신기는 응용 프로그램 두 개(*:7777/Foo 및 *:7777/Bar)가 TCP를 사용하도록 구성되어 있다는 알림을 받습니다. WAS는 또한 요청을 해당 대상 응용 프로그램과 연결하는 데 사용되는 고유한 수신기 채널 ID를 각 응용 프로그램에 할당합니다.

    수신기 프로세스는 WAS에서 제공하는 구성 정보를 사용하여 라우팅 테이블을 구성합니다. 라우팅 테이블은 수신기 프로세스가 도착하는 수신 요청을 수신기 채널 ID로 매핑하는 데 사용됩니다. 이 매핑의 메커니즘은 수신기가 지원하는 기본 프로토콜의 세부 구현입니다. 중요한 사실은 각 수신기 서비스는 수신 메시지를 확인하여 어떤 수신기 채널을 대상으로 하고 있는지 알아내고 적절하게 요청을 WAS로 발송할 수 있어야 한다는 것입니다. WCF는 TCP/MSMQ/명명된 파이프를 통해 도착하는 메시지의 대상을 나타내는 데 URI를 사용하고 있지만 다른 프로토콜에서는 이 매핑을 구현하는 데 어떠한 방법이라도 사용할 수 있습니다.

    수신기 서비스가 WAS에 연결하고 구성 정보를 받은 다음에는 해당 네트워크 리소스를 열어 메시지 수신을 시작할 수 있습니다. TCP의 경우에는 이에 따라 NetTcpActivator가 트리거되어 소켓을 열고 Socket.Accept에 대한 비동기 호출이 이루어집니다. 이 시점에 수신기는 기본적으로 메시지가 도착할 때까지 대기 상태가 됩니다.

    HTTP 이외의 프로토콜을 통한 메시지 기반 활성화

    메시지가 대기 중인 소켓에 도착하면 수신기 프로세스는 다시 작동을 시작하여 바이트를 읽습니다. 이 시점에서 목표는 차후 메시지의 궁극적인 대상을 확인할 수 있을 만큼 충분한 정보를 읽고, 수신기가 WAS에 대한 콜백을 수행하고 작업자 프로세스를 시작하는 동안 일시 중지하는 것입니다. TCP의 경우에는 SOAP 메시지를 둘러싸는 프레이밍 프로토콜에서 정보를 읽어 대상 주소 확인합니다. 수신기가 대상 URI를 얻은 다음에는 이 URI를 내부 라우팅 테이블에 대한 인덱스로 사용하여 WAS가 해당 주소에 할당한 해당 수신기 채널 ID를 확인합니다.

    그런 다음 수신기 서비스는 수신기 어댑터 인터페이스의 관리되지 않는 WebhostOpenListenerChannelInstance 메서드를 호출함으로써 작업자 프로세스를 활성화하여 보류 중인 요청을 처리하도록 WAS에 요청합니다. WebhostOpenListenerChannelInstance는 다른 매개 변수 외에도 활성화된 프로세스의 수신부의 기능을 초기화하는 데 사용될 수신기 채널 ID 및 바이트 배열로 표시되는 데이터 BLOB을 받습니다. 이 BLOB은 단지 각 프로토콜 수신기 구현이 새로 활성화한 구성 요소를 초기화하는 데 도움을 주기 위한 것이므로 WAS와는 관련이 없습니다.

    WAS가 WebhostOpenListenerChannelInstance에 대한 호출을 받으면 WAS의 프로세스 관리자 파트는 작업자 프로세스의 새 인스턴스를 시작합니다. 작업자 프로세스는 약간의 자체 초기화 작업을 수행해야 수신기가 수신한 메시지를 처리할 수 있습니다. 이 동안에 수신기는 계속해서 네트워크로부터 데이터를 수신할 수 있습니다. 그러나 작업자 프로세스 초기화가 완료되었다는 알림을 받기 전까지는 메시지를 작업자에게 발송할 수 없습니다.

    작업자 프로세스 초기화

    그림 3에서 볼 수 있는 것처럼 작업자 프로세스 내부에 활발하게 작업하는 몇 가지 중요한 구성 요소가 있습니다. 그림 4에서는 작업자 프로세스의 아키텍처를 보여 줍니다.

      Figure 3 작업자 프로세스의 중요한 구성 요소

    구성 요소
    설명

    프로세스 호스트
    작업자 프로세스에 CLR을 로드하고 기본 응용 프로그램 도메인을 초기화합니다.

    응용 프로그램 관리자
    응용 프로그램 수준 활성화 요청에 대한 응답으로 고유한 응용 프로그램 도메인을 만들고 각 도메인의 수명을 관리합니다.

    프로세스 프로토콜 처리기
    프로토콜별 프로세스 초기화 논리를 구현합니다.

    응용 프로그램 도메인 프로토콜 처리기
    활성화된 응용 프로그램 도메인에 위치하며 프로토콜별 응용 프로그램 도메인 초기화를 수행합니다.

    그림 4 작업자 프로세스 초기화 아키텍처 (더 크게 보려면 이미지를 클릭하십시오.)

    IIS에서는 관리되는 코드 구성 요소를 전혀 구현하고 있지 않으므로 CLR을 작업자 프로세스로 로드하는 작업은 ASP.NET 프로세스 호스트가 담당하게 되었습니다. WAS는 aspnet_isapi.dll에서 공개하는 API를 호출하여 작업자 프로세스 내에 프로세스 호스트를 만듭니다. WAS는 이 함수를 관리되는 프로세스 호스트가 WAS와의 이후 통신에 사용할 수 있는 콜백 인터페이스로 전달합니다. 그런 다음 새로 생성된 프로세스 호스트가 WAS로 반환되어, WAS와 작업자 프로세스 간의 양방향 통신이 가능해집니다.

    WAS는 작업자 프로세스에서 얻은 프로세스 호스트의 인스턴스를 사용하여 프로토콜별 초기화 루틴을 시작합니다. 프로세스 호스트의 활성화 시스템 StartProcessProtocolListenerChannel은 여기에 "net.tcp"와 같은 프로토콜 키, 그리고 프로토콜별 처리기에서 WAS와 다시 통신하는 데 사용할 수 있는 콜백 인터페이스를 전달합니다.

    프로세스 호스트가 작업자 프로세스 내부에서 새로운 프로세스 프로토콜 수신기 채널을 시작하기 위한 요청을 받으면 가장 먼저 구성에서 프로토콜 키를 조회합니다. WAS 사용자는 해당 수신기를 시작하기에 앞서 이를 등록해야 합니다. 예를 들어 WCF는 net.tcp용 프로세스 프로토콜 처리기와 응용 프로그램 도메인 프로토콜 처리기를 등록합니다. 그림 5에 표시된 구성 데이터는 %windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG에 있는 마스터 web.config 파일에 있습니다.

      Figure 5 net.tcp 프로토콜 처리기 구성

    코드 복사

    <system.web>
      <protocols>
        <add name="net.tcp"
         processHandlerType=
          "System.ServiceModel.WasHosting.TcpProcessProtocolHandler,
           System.ServiceModel.WasHosting, Version=3.0.0.0, Culture=neutral,
           PublicKeyToken=b77a5c561934e089"
         appDomainHandlerType=
          "System.ServiceModel.WasHosting.TcpAppDomainProtocolHandler,
           System.ServiceModel.WasHosting, Version=3.0.0.0, Culture=neutral,
           PublicKeyToken=b77a5c561934e089" validate="false" />
      </protocols>
    </system.web>

    프로세스 호스트는 구성에 있는 프로토콜 키를 확인하고, 기본 응용 프로그램 도메인에 구성된 프로세스 프로토콜 처리기 형식의 새 인스턴스를 만든 다음, 이에 대해 StartListenerChannel을 호출합니다. 이 메서드는 별도의 콜백 인터페이스 두 개를 받습니다. 이 중 하나는 WAS와 통신을 가능하게 하고(실제로 프로세스 호스트에 전달된 같은 WAS 콜백 개체임) 다른 하나는 프로세스 호스트와 직접 통신을 가능하게 합니다(그림 6 참조).

    그림 6 프로토콜 처리기 등록 (더 크게 보려면 이미지를 클릭하십시오.)

    PPH(프로세스 프로토콜 처리기)는 특정 프로토콜을 위한 호스팅 모델을 상당히 광범위한 수준으로 제어할 수 있습니다. 예를 들어 PPH는 간단히 초기화 루틴의 현재 시점에서 중지하고 기본 응용 프로그램 도메인에서 모든 후속 요청을 처리할 수 있습니다. 그러나 WCF는 각 응용 프로그램을 자체 응용 프로그램 도메인에 활성화함으로써 각각을 독립적으로 모니터링 및 재생할 수 있는 IIS 6.0 응용 프로그램 풀 모델을 유지하고 있습니다. 따라서 WCF PPH는 응용 프로그램과 응용 프로그램 도메인 수명을 결정하는 ASP.NET 응용 프로그램 관리자와 함께 작동해야 합니다.

    프로세스 호스트는 StartListenerChannel에 전달하는 IAdphManager 인터페이스를 통해 응용 프로그램 관리자의 기능에 대한 액세스를 PPH에 제공합니다. PPH는 활성화 요청에 대한 대상 응용 프로그램을 확인하기 위해 WAS에 대한 콜백을 수행하여 수신기가 원래 WebhostOpenListenerChannelInstance를 호출할 때 제공했던 데이터 BLOB을 요청합니다. 반환된 바이트 배열에 대한 약간의 작업을 수행한 다음 WCF PPH는 대상 응용 프로그램을 고유하게 식별하는 응용 프로그램 키에 액세스할 수 있게 됩니다(예: /w3svc/1/Foo). 이것은 WCF 수신기가 편의를 위해 수신기 채널에 전송하는 데이터 BLOB에 응용 프로그램 키를 추가한 덕분에 가능한 것입니다. WAS는 BLOB에 전달하는 데이터에 제한을 두지 않고 있습니다. WAS의 관점에서는 단지 내용을 볼 수 없는 바이트 배열일 뿐입니다. 그런 다음 응용 프로그램 키, 프로토콜 키 및 수신기 콜백 인터페이스를 IAdphManager.StartAppDomainProtocolListenerChannel에 전달하여 응용 프로그램의 응용 프로그램 도메인을 활성화할 수 있습니다.

    일반적으로 응용 프로그램 관리자는 응용 프로그램 키를 모든 응용 프로그램 도메인 테이블에 대한 인덱스로 사용합니다. StartAppDomainProtocolListener 호출을 수신하면 먼저 이 테이블을 참조하여 다른 프로토콜을 통해 도착한 이전 요청에 의해 응용 프로그램이 이미 활성화되었는지 여부를 확인합니다. 아무것도 찾지 못하면 프로세스 호스트에서 프로세스 프로토콜 처리기 형식을 확인하기 위해 이 키를 사용한 것과 거의 동일한 방법으로 프로토콜 키를 사용하여 프로토콜별 응용 프로그램 도메인 프로토콜 처리기 형식을 조회합니다. 응용 프로그램 도메인 프로토콜 처리기 형식이 확인되면 응용 프로그램 관리자는 대상 응용 프로그램 도메인에 이 형식의 새 인스턴스를 만듭니다. 최종적으로 응용 프로그램 관리자는 AppDomainProtocolHandler.StartListenerChannel을 호출하고 WAS 콜백 인터페이스를 다시 전달하여 응용 프로그램 도메인이 필요에 따라 WAS와 통신할 수 있도록 합니다.

    응용 프로그램 도메인 프로토콜 처리기가 인스턴스화되면 작업자 프로세스의 내부는 그림 7과 같은 형태를 갖게 됩니다. 이 시점에서 WAS는 대상 응용 프로그램이 완전히 활성화되었으며, 응용 프로그램이 종료되기 전까지 더 이상 프로세스에 관련될 부분이 없다고 간주합니다.

    그림 7 응용 프로그램 도메인 프로토콜 처리기 초기화 (더 크게 보려면 이미지를 클릭하십시오.)

    수신기에서 작업자로 데이터 이동

    작업자 프로세스와 응용 프로그램 도메인 활성화는 응용 프로그램에 메시지를 배달한다는 더 큰 목표를 향한 첫 번째 단계입니다. WAS는 활성화 서비스이며 메시지 배달 서비스가 아니므로 이 작업에 관여하지 않습니다. 대신 각 프로토콜 구현은 어떤 방법으로든 수신기와 작업자 간 통신을 자유롭게 구현할 수 있습니다. 이러한 아키텍처를 통해 다양한 프로토콜별 최적화가 가능하고 각 구현에서 기본 프로토콜의 특성을 활용할 수 있습니다. 예를 들어 WCF MSMQ 활성화 서비스는 단순히 데이터 BLOB의 MSMQ 큐 이름을 전달함으로써 활성화된 응용 프로그램이 수신기를 건너뛰어 직접 데이터 원본을 읽을 수 있도록 합니다.

    WAS에 WCF 서비스 호스팅

    이제 실제로 WAS에 WCF 서비스를 호스팅하는 작업을 시작하겠습니다. 먼저 HTTP 기반 서비스를 설정합니다. 이 작업은 IIS 6.0에서와 크게 다르지 않습니다. 그 다음 TCP, 명명된 파이프, MSMQ에 대한 지원을 추가하고 사용 가능한 구성 옵션에 대해 자세히 살펴보겠습니다(간단한 서비스의 소스 코드는 그림 8 참조).

      Figure 8 샘플 WCF 서비스

    코드 복사

    [ServiceContract(Name = "WasDemoServiceContract", 
                    Namespace = "urn:msdnmag")]
    public interface IDemoService
    {
      [OperationContract(Name="Ping", Action="Ping", 
                         ReplyAction="PingReply")]
      string Ping(string data);
    }
    
    [ServiceBehavior(
      Name="WasDemoService", Namespace="urn:msdnmag",
      InstanceContextMode=InstanceContextMode.PerCall,
      ConcurrencyMode=ConcurrencyMode.Single)]
    public class DemoService : IDemoService
    {
      public string Ping(string data)
      {
        return "pinged with: " + data;
      }
    }

    첫 번째 단계는 WAS에 새 응용 프로그램을 만드는 것입니다. 이 작업은 IIS 7.0 관리 도구 또는 Visual Studio®를 사용하여 수행할 수 있습니다. 가상 디렉터리에는 세 가지 요소, 즉 서비스(/bin 디렉터리에 컴파일된 상태 또는 /App_Code 폴더의 소스 코드), .svc 서비스 끝점, 그리고 구성 파일이 있습니다.

    .svc 파일은 URI와 서비스 구현을 연결합니다(.asmx 파일과 매우 유사함). .svc 파일 내의 @ServiceHost 지시문은 Service 특성에 지정된 형식에 대한 ServiceHost 인스턴스를 만들도록 WCF에 지시합니다.

    코드 복사

    <% @ServiceHost Service="DemoService" %>

    WAS에 대한 구성 정보는 web.config 파일에 저장됩니다. 전체 WCF 구성은 system.serviceModel 섹션에서 수행됩니다. 여기에서 한 가지 주목할 부분은 WAS를 호스팅할 때 기준 주소를 지정하지 않는다는 점입니다. 이 주소는 웹 사이트와 가상 디렉터리 시스템에 의해 결정되기 때문입니다(기본 구성 파일은 그림 9 참조). 구성된 서비스 동작은 메타데이터 게시를 활성화하며, svcutil.exe와 같은 도구 또는 Visual Studio의 "서비스 참조 추가" 대화 상자를 직접 가리켜 클라이언트측 프록시를 생성할 수 있습니다.

      Figure 9 샘플 서비스의 기본적인 구성

    코드 복사

    <configuration>
      <system.serviceModel>
        <services>
          <service name="DemoService" behaviorConfiguration="Behavior">
            <endpoint address="" binding="wsHttpBinding"
             bindingNamespace="urn:msdnmag" contract="IDemoService" />
          </service>
        </services>
        ...
        <behaviors>
          <serviceBehaviors>
            <behavior name="Behavior">
              <serviceMetadata httpGetEnabled="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>

    HTTP 전송을 사용하는 WCF 끝점은 공용 IIS 처리 파이프라인을 거칩니다. 예전에 ASP.NET 웹 서비스 작업을 했었다면 이 부분이 매우 익숙하게 느껴지겠지만 내부적인 동작은 약간 다릅니다. 여기에는 ASP.NET 호환 모드와 호환되지 않는 모드, 즉 두 가지의 HTTP 기반 끝점 작업 모드가 있습니다. 기본적으로 ASP.NET 호환성은 해제되어 있으며 이는 HttpContext.Current가 null이고 실질적인 끝점 활성화는 HttpHandler가 아닌 HttpModule에서 발생함을 의미합니다. HttpModule은 ASP.NET PostAuthenticateRequest 파이프라인 이벤트의 ServiceHost로 요청을 넘깁니다. 여기에는 몇 가지 의미가 내포되어 있습니다. 먼저 ASP.NET 확장성 모델에 익숙하다면 PostAuthenticateRequest까지만 파이프라인 알림을 수신하게 됩니다. 거기서부터 처리는 EndRequest 이벤트로 직접 이동하게 됩니다. 또한 WCF 서비스는 세션 상태를 비롯한 모든 ASP.NET 호스트 기능에 액세스할 수 없게 됩니다. 이것은 의도된 동작입니다. WCF 서비스 호스트에는 이러한 모든 기능(세션, 인증 등)에 해당하는 전송 독립적 항목이 있으므로 특정 호스팅 환경에 서비스를 묶으려 시도하면 안 됩니다.

    ASP.NET 호환성이 꼭 필요하다면(예를 들어 동일한 응용 프로그램 도메인에 호스팅되는 AST.NET 응용 프로그램과 서비스 간에 세션 상태를 공유하려는 경우) 다음과 같이 구성 스위치를 사용하여 이를 설정할 수 있습니다.

    코드 복사

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

    또한 다음과 같이 ASP.NET 호환성에 대해 서비스를 명확히 활성화해야 합니다.

    코드 복사

    [AspNetCompatibilityRequirements(
        RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    class DemoService : IDemoService { ... }

    이 두 스위치의 조합은 서비스 요청 작업의 내부 처리 방식을 변경합니다. 두 스위치가 사용되면 요청은 HttpHandler를 사용하여 WCF 런타임으로 발송되며 전체 처리 파이프라인은 ASP.NET 웹 서비스와 매우 비슷하게 동작합니다. 또한 현재 HttpContext가 제공되므로 평소와 같이 사용할 수 있습니다. ASP.NET 호환 모드로 실행되는 WCF 서비스는 HTTP 끝점만 지원합니다.

    WAS에 HTTP 기반 서비스를 호스팅하는 방법을 알았으니 이제 서비스에 HTTP 이외의 끝점을 추가해 보겠습니다. 앞서 설명한 바와 같이 프로토콜 수신기는 실제 전송을 여는 역할, 그리고 서비스를 실행하는 응용 프로그램 도메인으로 연결을 발송하는 역할을 합니다. 이러한 프로토콜 수신기는 Windows NT 서비스입니다. services.msc를 열면 Net.tcp 수신기 어댑터와 명명된 파이프 및 MSMQ를 위한 수신기를 볼 수 있습니다. HTTP 이외의 활성화를 성공적으로 수행하려면 이러한 항목들과 TCP를 위한 포트 공유 서비스가 모두 실행 중이어야 합니다.

    수신기 어댑터의 호스트 이름과 포트 구성은 WAS 구성 파일인 applicationHost.config에서 찾을 수 있습니다. 설정을 수동으로 편집하거나 appcmd.exe 명령줄 도구 또는 IIS 7.0 구성 GUI를 사용할 수 있습니다. 바인딩이라고 하는 이러한 설정은 사이트 수준에서 수행됩니다(그림 10 참조). Windows Vista에서 제공되는 WAS와 Windows Server 2008에서 제공되는 WAS의 버전은 약간 다릅니다. Windows Vista에서 바인딩은 미리 구성되지 않으며 현재로서는 그래픽 방식으로 이를 추가하기 위한 GUI가 없습니다. 필요한 appcmd.exe 명령은 나중에 살펴보겠습니다. Windows Server 2008에서 바인딩은 기본적으로 구성되어 있습니다.

    그림 10 IIS 6.0 기본 인증 (더 크게 보려면 이미지를 클릭하십시오.)

    그림 10 IIS 6.0 기본 아키텍처

    코드 복사

    <bindings>
      <binding protocol="https" bindingInformation="*:443:" />
      <binding protocol="http" bindingInformation="*:80:" />
      <binding protocol="net.tcp" bindingInformation="808:*" />
      <binding protocol="net.pipe" bindingInformation="*" />
      <binding protocol="net.msmq" bindingInformation="localhost" />
      <binding protocol="msmq.formatname" bindingInformation="localhost" />
    </bindings>

    각 프로토콜에는 bindingInformation 특성에 프로토콜별 구성 설정이 있습니다. 예를 들어 TCP 바인딩에 대한 bindingInformation은 포트, 그리고 수신기가 연결을 허용하는 호스트 이름을 지정합니다. * 기호를 사용하면 모든 호스트 이름이 유효하게 됩니다.

    마지막 단계는 서비스를 호스팅하는 응용 프로그램에서 선택한 프로토콜을 활성화하는 것입니다. Windows Server 2008 베타 3을 기준으로 이 작업을 위한 GUI는 없습니다. 따라서 applicationHost.config 파일을 수동으로 편집해야 합니다. 나중에 도구를 사용하여, 또는 프로그래밍 방식으로 이 작업을 처리하는 방법을 살펴보겠습니다. 구성 파일에서 응용 프로그램 요소를 검색한 후 다음과 같이 enabledProtocols 특성을 추가합니다.

    코드 복사

    <application path="/WasDemo" 
        enabledProtocols="http,net.tcp,net.pipe,net.msmq">
      <virtualDirectory path="/" physicalPath="C:\MSDN\WasDemo\web" />

    그 다음 위의 프로토콜을 통해 연결할 수 있도록 WCF 서비스 구성에 끝점을 추가하기만 하면 됩니다.

    코드 복사

    <endpoint address="" binding="netTcpBinding"
      bindingNamespace="urn:msdnmag" contract="IDemoService" />
    <endpoint address="" binding="netNamedPipeBinding"
      bindingNamespace="urn:msdnmag" contract="IDemoService" />

    메타데이터에서 클라이언트 프록시를 생성할 경우 구성 파일에는 각 끝점에 대한 클라이언트 요소가 포함됩니다. 클라이언트 코드에서 다음과 같이 프록시 생성자에 끝점 이름을 전달하여 사용할 전송을 지정할 수 있습니다.

    코드 복사

    WasDemoServiceContractClient proxyTcp = 
      new WasDemoServiceContractClient(
        "NetTcpBinding_WasDemoServiceContract");
    Console.WriteLine(proxyTcp.Ping("Hello"));

    서비스에 MSMQ 끝점을 추가하려면 몇 가지 단계가 더 필요합니다. 먼저 메시지 큐 MMC 스냅인 또는 사용 가능한 프로그래밍 방식을 사용하여 큐를 생성해야 합니다. 또한 작업자 프로세스(기본적으로 NETWORK SERVICE)가 큐를 읽고 볼 수 있도록 큐에 ACL(액세스 제어 목록)을 설정해야 합니다.

    MSMQ 끝점 활성화는 큐 이름이 시스템 이름을 뺀 .svc 파일과 동일한 경우에만 올바르게 작동한다는 점이 중요합니다. 즉, 서비스 끝점이 /server/app/service.svc라면 큐 이름은 app/service.svc여야 합니다.

    서비스 구성에서 서비스가 수신해야 하는 큐의 이름을 다음과 같이 지정해야 합니다.

    코드 복사

    <endpoint address="net.msmq://localhost/private/wasdemo/service.svc"
      binding="netMsmqBinding" bindingNamespace="urn:msdnmag"
      contract="IServiceMsmq" />

    HTTP 이외의 끝점은 IIS 처리 파이프라인을 전달하지 않으며 WCF 런타임으로 직접 라우팅됩니다. 이는 HttpModule을 사용하여 요청을 사전 또는 사후 처리할 수 없음을 의미합니다. 또한 HttpApplication 클래스(global.asax)의 Application_Start와 Application_End가 실행되지 않습니다. 따라서 이러한 서비스에 대한 시작 또는 정리 코드를 실행하려면 ServiceHost 클래스의 이벤트를 사용해야 합니다. 다음 섹션에서 이러한 방식의 동작 원리를 자세히 살펴보겠습니다.

    WAS에서 호스팅되는 서비스의 수명 관리

    서비스를 자체 호스팅하는 경우(예: Windows NT 서비스 내) 해당 서비스의 수명은 명확합니다. 서비스는 Open 호출 이후 실행되어 Close 호출 이후 종료됩니다(오류가 발생하는 경우 제외). 또한 Windows NT 서비스는 대개 부팅 시 시작됩니다. WAS에 호스팅하는 경우 상황은 달라집니다.

    우선 WAS에서는 활성화가 필요합니다. 아시다시피 "WAS"의 "A"는 활성화(Activation)를 의미합니다. 이는 서비스를 호스팅하는 응용 프로그램 도메인은 요청 메시지가 오는 경우에만 생성됨을 의미합니다. 유휴 기간(구성 가능함)이 지나면 응용 프로그램 도메인은 다시 종료됩니다. WAS 또는 ASP.NET 런타임이 응용 프로그램 도메인, 심지어 전체 작업자 프로세스까지 재생하기로 결정하는 데는 여러 가지 이유가 있습니다.

    우선 WAS의 응용 프로그램 풀 설정이 작업자 프로세스의 정기적 재생을 지정하며 기본값은 29시간입니다. 29라는 소수가 선택된 이유는 재생이 동일한 시간에 발생할 가능성을 최소화하기 위해서입니다.

    응용 프로그램 도메인이 재생되는 데에는 여러 다른 이유도 있습니다. 이 응용 프로그램 도메인에 영향을 미치는 machine.config, web.config 또는 applicationHost.config의 구성 설정이 변경되었을 수 있습니다. 또한 /bin이나 /App_Code 디렉터리 또는 해당 내용이 수정되었거나 다시 컴파일(.aspx, .asmx, .svc 등) 횟수가 machine.config 또는 web.config의 <compilation numRecompilesBeforeAppRestart /> 설정에 지정된 제한(기본값 15)을 초과하거나 가상 디렉터리의 실제 경로가 변경되었을 수 있습니다. 마지막으로, CAS(코드 액세스 보안) 정책이 수정되었거나 응용 프로그램 하위 디렉터리가 삭제되었을 수 있습니다. 이러한 경우가 발생하면 세션 또는 인스턴스 및 정적 변수를 포함한 모든 메모리 내 상태를 잃게 됩니다. 이는 기본적인 WAS 호스팅이 세션 또는 단일 서비스에 적합하지 않음을 의미합니다. 기본 WAS 호스팅은 상태를 저장하지 않는 호출별 서비스에 적합합니다.

    WCF ServiceHost 형식에는 Opening과 Closing이라는 두 개의 이벤트가 있습니다. 서비스 시작 및 종료 시에 적절히 코드를 실행하려면 이 두 이벤트를 사용하는 방법 외에는 없습니다. 문제는 새 ServiceHost 인스턴스를 만들고 여기에서 Open을 호출하는 작업 사이에 이러한 이벤트를 위한 처리기를 작성해야 한다는 점입니다. 이는 앞에서 설명한 대로 .svc 파일의 @ServiceHost 지시문을 사용할 경우 불가능합니다. 이 경우 가능한 옵션은 사용자 지정 서비스 호스트 팩터리를 호스팅하는 것입니다. 이렇게 하면 보다 폭넓은 제어가 가능하며 앞서 언급한 이벤트를 처리할 수 있습니다.

    이렇게 하려면 ServiceHostFactoryBase라는 클래스에서 파생시킨 다음 CreateServiceHost 메서드를 구현해야 합니다. 이 메서드는 호스팅 환경에서 서비스 형식 이름과 기준 주소를 받아 ServiceHostBase 인스턴스를 반환합니다. 이제 적절한 ServiceHost를 만들고 필요에 따라 이를 구성하고 WCF 런타임에 반환하는 작업은 개발자의 몫입니다. 이렇게 하면 WCF의 확장성 모델에 프로그래밍 방식으로 액세스하고 이벤트 처리기를 연결할 수 있습니다(그림 11 참조).

      Figure 11 CreateServiceHost 사용

    코드 복사

    public class HostFactory : ServiceHostFactoryBase
    {
      public override ServiceHostBase CreateServiceHost(
        string constructorString, Uri[] baseAddresses)
      {
        Type service = Type.GetType(constructorString);
        ServiceHost host = new ServiceHost(service, baseAddresses);
        // hook up event handlers
        host.Opening += OnOpening;
        host.Closing += OnClosing;
        return host;
      }
    }

    이미 있는 .svc 끝점과 사용자 지정 팩터리 사이에 연결을 설정하려면 다음과 같이 @ServiceHost 지시문에 Factory 특성을 추가해야 합니다.

    코드 복사

    <%@ServiceHost Service="Service" Factory="HostFactory" %>

    WAS에서 호스팅되는 서비스의 자동 설정

    앞서 설명했듯이 WAS에서 호스팅되는 WCF 서비스를 설정하기 위해서는 다음과 같은 여러 단계가 필요합니다.

    1. 실제 디렉터리를 설정합니다(필요한 경우 ACL도 설정).
    2. WAS에 응용 프로그램 및 가상 디렉터리를 설정합니다.
    3. 활성화된 프로토콜을 구성합니다.
    4. 큐를 만들고 ACL을 설정합니다(MSMQ가 사용되는 경우).

    WAS는 WMI(Windows Management Instrumentation), 명령줄 도구(appcmd.exe), 그리고 새로운 관리 API를 비롯한 다양한 구성 인터페이스를 제공합니다. WMI와 appcmd.exe가 스크립팅 및 배치 파일에 적합한 반면 새로운 관리 API는 MSI 패키지와 같이 보다 복잡한 배포 구성에 대한 손쉬운 액세스를 제공합니다. 그림 12에는 몇 가지 appcmd.exe 예제가 나와 있습니다.

      Figure 12 appcmd.exe를 사용한 WAS 응용 프로그램 설정

    코드 복사

    REM adding bindings to the default web site
    appcmd.exe set site "Default Web Site" –
        +bindings.[protocol='net.tcp',bindingInformation='808:*']
    appcmd.exe set site "Default Web Site" –
        +bindings.[protocol='net.pipe',bindingInformation='*']
    appcmd.exe set site "Default Web Site" –
        +bindings.[protocol='net.msmq',bindingInformation='localhost']
    
    REM add a new application
    appcmd add app /site.name:"Default Web Site" /path:/WasDemo 
        /physicalpath:c:\etc\WasDemo
    
    REM enabled protocols for application
    appcmd.exe set app "Default Web Site/WasDemo" 
        /enabledProtocols:http,net.pipe,net.tcp,net.msmq

    관리되는 구성 API는 새로운 Microsoft.Web.Administration.dll 어셈블리에 있으며 ServerManager 클래스를 중심으로 구성됩니다. 여기에서 응용 프로그램 풀, 작업자 프로세스, 사이트, 응용 프로그램 및 구성 파일을 포괄하는 완전한 개체 모델을 찾을 수 있습니다. 이 API를 사용한 응용 프로그램 설정은 그림 13에서 볼 수 있듯이 몇 줄의 코드만으로 끝납니다. 그림 14에서는 NETWORK SERVICE 계정을 위한 최소 ACL 및 큐를 설정하는 간단한 도우미 메서드를 볼 수 있습니다.

      Figure 14 큐 생성 및 ACL 설정

    코드 복사

    private static void SetupMsmq(string queuename)
    {
      // create queue – in this case a transactional queue is created
      MessageQueue queue = MessageQueue.Create(queuename, true);
      queue.Label = queuename;
    
      // set ACL
      queue.SetPermissions(GetAccountName(
        WellKnownSidType.NetworkServiceSid), 
        MessageQueueAccessRights.ReceiveMessage);
    }
    
    private static string GetAccountName(WellKnownSidType wellKnownSid)
    {
      NTAccount account = (NTAccount) new SecurityIdentifier(wellKnownSid,
        null).Translate(typeof(NTAccount));
      return account.Value;
    }

      Figure 13 관리되는 구성 API 사용

    코드 복사

    private static void SetupWasApp(string virtualPath, string physicalPath,
      string enabledProtocols)
    {
      ServerManager manager = new ServerManager();
    
      // creating the application
      manager.Sites[0].Applications.Add(virtualPath, physicalPath);
      manager.CommitChanges();
    
      // setting up the enabled protocols
      Application wasApp = manager.Sites[0].Applications[virtualPath];
      wasApp.EnabledProtocols = enabledProtocols;
      manager.CommitChanges();
    }

    WAS 확장

    WAS는 확장 가능하므로 사용자 지정 WCF 전송 채널에 대한 지원을 직접 작성할 수 있습니다. Windows SDK에는 UDP(User Datagram Protocol) 기반 WAS 활성화 확장을 위한 샘플이 포함되어 있지만 WAS를 확장하여 자신만의 기능을 추가하기란 간단한 작업이 아닙니다. 이를 위해서는 사용자 지정 프로세스와 응용 프로그램 도메인 프로토콜 처리기를 구현해야 할 뿐만 아니라 각각의 대상 전송 메커니즘에서 메시지를 받기 위한 수신 코드도 작성해야 합니다. 이에 대해 충분히 설명하려면 별도의 심층적 기사가 필요합니다.

    어쨌든 반드시 언급해야 할 한 가지 핵심 사항이 있습니다. WAS의 최대 요청 실행 제한 값은 해당 OS에 따라 다릅니다. Windows Server 2008에서는 무제한이지만 Windows Vista Ultimate와 Business에서는 10회 연결로 제한됩니다. 가정용 Windows Vista 버전인 Windows Vista Home Basic과 Home Premium, 그리고 Windows Vista Starter의 요청 실행 제한은 3회입니다. 구현을 계획할 때 이 점을 염두에 두시기 바랍니다.

    Dominick Baier는 독일 thinktecture(thinktecture.com)에서 보안 컨설턴트로 일하고 있습니다. 그는 DevelopMentor(develop.com)의 보안 및 WCF 커리큘럼을 이끌고 있으며, 개발자 보안 MVP이고, Developing More Secure Microsoft ASP.NET 2.0 Applications(Microsoft Press, 2006)를 저술하기도 했습니다. Dominick Baier의 블로그 주소는 leastprivilege.com입니다.

    Christian Weyer는 thinktecture 공동 창립자이자 수석 설계자이며 Java, COM, DCOM, COM+, Web Services, WCF 및 기타 여러 기술을 사용해 분산 응용 프로그램을 모델링 및 구현하고 있습니다. 문의 사항이 있으면 thinktecture.com/staff/christian을 통해 연락하십시오.

    Steve Maine은 Microsoft Connected Framework 팀에서 선임 프로그램 관리자로 일하고 있습니다. 현재 그는 곧 릴리스될 .NET Framework 3.5의 WCF를 위한 다양한 웹 중심 프로그래밍 모델 기능을 개발하고 있습니다. Steve Maine의 블로그 주소는 hyperthink.net/blog입니다.

    Current Issue

    MSDN Magazine December 2009 Issue

    Browse All MSDN Magazines

    기본적인 형태의 프로젝트 구조

     

    계약된 웹서비스를 만들기 위한 인터페이스

    using System.ServiceModel;
    using System.ServiceModel.Description;

    namespace IChannel
    {
        [ServiceContract]
        public  interface IHelloWorld
        {
            [OperationContract]
            string Hellworld();
        }
    }

     

    웹서비스(서버측)

    using IChannel;

    namespace WcfService1
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
        public class Service1 : IService1 , IChannel.IHelloWorld
        {
            public string GetData(int value)
            {
                return string.Format("You entered: {0}", value);
            }

            string IHelloWorld.Hellworld()
            {
                return "TEST MODE";
            } 
        }
    }

     

    클라이언트에서 호출

    Icannerl 이 참조되어져 있습니다.

    string uri = "http://localhost:49724/Service1.svc";

    ServiceEndpoint ep = new ServiceEndpoint(ContractDescription.GetContract(typeof(IChannel.IHelloWorld)), new wsHttpBinding(), new EndpointAddress(uri));
    ChannelFactory<IChannel.IHelloWorld> factory = new ChannelFactory<IChannel.IHelloWorld>(ep);
    IChannel.IHelloWorld proxy = factory.CreateChannel();

    string result = proxy.Hellworld();
    (proxy as IDisposable).Dispose();

    MessageBox.Show(result);      


    서버측 웹컨피그 수정 
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="MarinerERP.WebService.DataService.InsaServiceBehavior">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service behaviorConfiguration="MarinerERP.WebService.DataService.InsaServiceBehavior"
            name="MarinerERP.WebService.DataService.InsaService">
            <endpoint address="" binding="wsHttpBinding" contract="IChannel.IHelloWorld "> //인터페이스로 맞추어주어야 합니다.
              <identity>
                <dns value="localhost" />
              </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
      </system.serviceModel>


    contract 는 웹서비스와 클라이언트와의 계약이기 때문에 꼭 맞추어 주세요!

     

     

    '/' 응용 프로그램에 서버 오류가 있습니다.

    최대 요청 길이를 초과했습니다.

    설명: 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 스택 추적을 검토하여 발생한 오류 및 코드에서 오류가 발생한 위치에 대한 자세한 정보를 확인하십시오.
    예외 정보: System.Web.HttpException: 최대 요청 길이를 초과했습니다.
    소스 오류:

    현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 생성되었습니다. 아래의 예외 스택 추적을 사용하여 예외의 원인 및 위치 정보를 확인할 수 있습니다.

    스택 추적:

    [HttpException (0x80004005): 최대 요청 길이를 초과했습니다.]
       System.Web.HttpRequest.GetEntireRawContent() +3315778
       System.Web.HttpRequest.GetMultipartContent() +56
       System.Web.HttpRequest.FillInFormCollection() +222
       System.Web.HttpRequest.get_Form() +65
       System.Web.HttpRequest.get_HasForm() +3309630
       System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +45
       System.Web.UI.Page.DeterminePostBackMode() +65
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +133


    버전 정보: Microsoft .NET Framework 버전:2.0.50727.1433; ASP.NET 버전:2.0.50727.1433

    web.config 에 다가 아래 항목추가하면됩니다

    <!--

          파일 용량설정
    -->
        <httpRuntime  maxRequestLength="52100" ></httpRuntime>

    .NET Framework 일반 참조

    httpRuntime 요소(ASP.NET 설정 스키마)

    ASP.NET 응용 프로그램에 대한 요청을 처리하는 방법을 결정하는 ASP.NET HTTP 런타임 설정을 구성합니다.

    configuration 요소(일반 설정 스키마)
    system.web 요소(ASP.NET 설정 스키마)
    httpRuntime 요소(ASP.NET 설정 스키마)

    선택적 Int32 특성입니다.

    입력 스트림 버퍼링 임계값 제한(KB)을 지정합니다. 이 제한을 설정하면 예를 들어 사용자가 서버에 큰 파일을 게시할 때 발생하는 서비스 거부 공격을 방지할 수 있습니다.

    기본값은 4096(4MB)입니다.

    + Recent posts