본문 바로가기

IT 살이/04. 기술 - 프로그래밍

개발 프레임워크 만들기 대장정 45 - 서비스 구성하기

이번 포스트부터는 달봉이가 제작한 ServiceProxyFactory 객체를 이용해서 동기 호출과 비동기 호출에 대한 코딩 예를 보여준다.

 

■ IIS 서비스 환경 구성하기

 

우선 서버측 서비스를 구성해 보자. 달봉이는 서비스 구현 프로젝트와 서비스 노출 프로젝트를 분리했다. 서비스 구현은 BONG.SVC.CO.UserMgmt에 있고, 노출 프로젝트는 웹 애플리케이션을 이용한다.

SampleService.cs에는 다음처럼 간단한 서비스가 구현되어 있다. 다음 코드는 사용자 정보를 서버측으로 전달하는 과정을 설명하는 포스트에서도 봤다.

namespace BONG.SVC.CO.UserMgmt

{

    [ServiceContract]

    public interface ISampleService

    {

        [OperationContract]

        string Hello();

    }

    public class SampleService : Dalbong2ServiceBase, ISampleService

    {

        public string Hello()

        {

            //실행 좀 멈춘다.

            System.Threading.Thread.Sleep(10000);

            //현재 사용자의 ID를 사용한다

            return String.Format("Hello, you're {0}", base.UserInfo.ID);

        }

    }

}

이제 이 서비스를 외부로 노출시키자. 달봉이는 이 WCF 서비스 노출을 위해서 IIS를 이용하고 있다.

탐색기를 열어 달봉이의 폴더 구조를 보면 다음과 같이 되어 있다.

03 SVC 폴더를 기본 웹 사이트의 가상 디렉토리로 만들었다.

달봉이는 가상 디렉토리명을 “BongSvc”로 했다.

다음 CO 폴더를 보면 WCF 구현을 포함하고 있는 BONG.SVC.CO.UserMgmt 폴더가 있다. 이제 이것을 노출할 서비스를 만들기 위해서 BONG.CO.UserMgmt.Service폴더를 하나 더 만들자.

이제 IIS 관리 콘솔에서 BONG.CO.UserMgmt.Service에 대한 웹 애플리케이션을 하나 만들자. IIS 관리 콘솔에서 BONG.CO.UserMgmt.Service를 오른쪽클릭하면 다음과 같은 메뉴가 보인다.

이 중에서 “Convert to Application” 메뉴를 선택한다. 다음과 같은 애플리케이션 추가 창이 뜬다.

다른 값은 기본값을 사용하고, Application pool을 다른 값으로 선택할 수도 있다.

달봉이는 DalbongAppPoos( 미스 스펠링 –_-;;)을 미리 만들어 두었다. 하지만 지금은 DefaultAppPool을 사용해도 상관없다.

OK버튼을 클릭하면 다음처럼 애플리케이션이 생성된다.

이제 Visual Studio로 가자. UserMgmt 폴더를 오른쪽 클릭해서 “New Web Site…”를 선택한다.

 

템플릿에서 “WCF Service”를 선택한다.

“Browse…”버튼을 클릭해서 앞에서 만들어 놓은 웹 애플리케이션을 선택한다.

작업을 마치고 나면 Visual Studio는 다음처럼 된다.

샘플로 WCF 구현을 만들어놓은 IService.cs와 Service.cs, Service.svc가 있다.  달봉이는 이미 BONG.SVC.CO.UserMgmt에 서비스를 구현해 놨다. 해서 앞의 녀석들을 삭제한다. WCF 서비스 프로젝트를 오른쪽 클릭해서 새 항목을 추가하도록 하자.

WCF Service 템플릿을 선택하고 페이지 이름을 “SampleService.cs”로 한다. 자동 생성되는 ISampleService.cs, SampleService.cs 파일을 삭제한다.

이제 서비스를 구현해 놓은 BONG.SVC.CO.UserMgmt에 대한 참조를 추가하자. WCF 프로젝트를 선택해서 오른쪽 클릭을 한 다음 “Property pages”를 선택한다.

“Add…”버튼을 클릭한다.

Projects 탭에서 BONG.SVC.CO.UserMgmt를 선택한다.

이제 SampleService.svc 페이지를 더블 클릭하면 다음과 같은 서비스 선언문이 나타난다.

<%@ ServiceHost="" Language="C#" Debug="true" Service="SampleService" CodeBehind="~/App_Code/SampleService.cs" %>

Codebehind 부분을 제거하고, 다음처럼 수정한다.

<%@ ServiceHost="" Language="C#" Debug="true" Service="BONG.SVC.CO.UserMgmt.SampleService"  %>

이제 Web.config 파일을 수정해야 한다.

<system.serviceModel>

    <behaviors>

        <serviceBehaviors>

            <behavior name="SampleServiceBehavior">

                <serviceMetadata httpGetEnabled="true" />

                <serviceDebug includeExceptionDetailInFaults="false" />

            </behavior>

        </serviceBehaviors>

    </behaviors>

    <services>

        <service behaviorConfiguration="SampleServiceBehavior" name="BONG.SVC.CO.UserMgmt.SampleService">

            <endpoint address="" binding="wsHttpBinding" contract="BONG.SVC.CO.UserMgmt.ISampleService">

                <identity>

                    <dns value="localhost" />

                </identity>

            </endpoint>

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

        </service>

    </services>

</system.serviceModel>

볼드체로 되어 있는 부분이 SampleService, ISampleService로 되어 있을 것이다. 이 녀석들을 위 코드처럼 수정한다. 서비스 선언문의 Service 어트리뷰트값과 web.config의 <service>의 name 어트리뷰트값이 일치해야 한다.

이제 Visual Studio에서 SampleService.svc 항목을 오른쪽 클릭해서 View in browser를 선택한다. 제대로 되었다면 다음과 같은 페이지가 출력된다.

이제 서버측 서비스 구성은 다 끝났다. 브라우저에 보이는 주소를 복사해뒀다가 클라이언트에서 서비스를 참조할때 사용하면 된다.

 

■ WCF 서비스 확장 설정하기

 

앞의 web.config에 이전 포스트에서 보았던 사용자 정보를 받기 위한 configuration을 추가한다. 그럼 완전한 <system.serviceModel/>모습은 다음과 같이 된다.

<system.serviceModel>

    <services>

        <service behaviorConfiguration="SampleServiceBehavior"

                 name="BONG.SVC.CO.UserMgmt.SampleService">

            <endpoint address=""

                      binding="wsHttpBinding"

                      behaviorConfiguration="MyEndPointInspectors"

                      contract="BONG.SVC.CO.UserMgmt.ISampleService">

                <identity>

                    <dns value="localhost" />

                </identity>

            </endpoint>

            <endpoint address="mex"

                      binding="mexHttpBinding"

                      contract="IMetadataExchange" />

        </service>

    </services>

    <behaviors>

        <serviceBehaviors>

            <behavior name="SampleServiceBehavior">

                <serviceMetadata httpGetEnabled="true" />

                <serviceDebug includeExceptionDetailInFaults="false" />

            </behavior>

        </serviceBehaviors>

        <endpointBehaviors>

            <behavior name="MyEndPointInspectors">

                <UserInfoEndpointExtention/>

            </behavior>

        </endpointBehaviors>

 

    </behaviors>

 

   <extensions>

        <behaviorExtensions>

            <add name="UserInfoEndpointExtention"

                 type="Dalbong2.Service.Interceptors.UserInfoBehaviorExtensionElement, Dalbong2.Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

        </behaviorExtensions>

    </extensions>

</system.serviceModel>

한가지 주의할 것이 있다.

마지막 부분에서 type 어트리뷰트값이 길지만, 타입명과 어셈블리명 사이를 반드시 같은 줄에 적어줘야 한다. 뿐만 아니라 타입명과 어셈블리명 사이에 반드시 하나의 공백을 둬야 한다. 안그러면 고생 좀 하게 될 것이다. 달봉이가 보기에는 뭐 특별한 이유가 있는 것이 아니라, configuration 컴파일러 개발자가 빨리 만들고 어디 놀러갈 일이 있었나 보다. 덕분에 달봉이 많이 고생했다.

이것으로 서버측 서비스 설정은 끝났다. 다음 포스트에서는 클라이언트측에서의 서비스 호출을 알아보도록 한다.