프로그래밍 기술/웹 검색 엔진 만들기

10. 검색 서비스 만들기

언제나휴일 2017. 12. 7. 10:58
반응형

10. 검색 서비스 만들기


 

 이번에는 랭커 라이브러를 이용하여 검색 서비스를 만듭시다. 아키텍쳐링 단계에서 검색 서비스는 웹 서비스로 약속하였는데 여기에서는 .NET 리모팅 서비스로 만들게요.

 

 .NET 리모팅 서비스를 만들려면 먼저 리모팅 서버와 리모팅 클라이언트에서 공통으로 참조하는 라이브러리가 필요합니다.

 

 따라서 여기에서는 공통으로 참조하는 라이브러리 작성 후에 리모팅 서버를 작성하고 이를 사용하는 클라이언트 예광탄을 만듭시다.

 

10.1 공통 라이브러리 만들기

 

 검색 서비스와 클라이언트에서 사용할 공통 라이브러리를 만듭시다. 공통 라이브러리 이름은 GenericSearchLib라고 할게요.

 

 공통 라이브러리로 랭커 라이브러리를 직접 사용하는 것은 클라이언트 측에 주요 라이브러리를 배포하는 결과를 초래하므로 여기에서는 리플렉션을 이용하여 래핑한 클래스를 제공하기로 합시다.

 

 여러분께서 아시는 것처럼 .NET 리모팅 서버스로 제공할 공통 라이브러리의 클래스는 MashalByRefObject에서 파생한 형식이여야 합니다. GenericSearch 클래스 이름으로 정의할게요.

public class GenericSearch:MarshalByRefObject

{

}

 

 검색 서비스에서는 랭커 라이브러리를 참조합니다. 그리고 입력 인자로 검색 질의를 받고 결과로 RankedUrl 목록을 반환합니다. 그런데 .NET 리모팅에서는 제네릭 컬렉션을 인자로 사용할 수가 없으므로 ArrayList를 반환하는 것으로 할게요.

public ArrayList Request(string query)

 

 메서드에서는 제일 먼저 랭커 라이브러리를 로딩하고 랭커 라이브러의 Ranker 형식을 얻어옵니다.

Assembly asm = Assembly.Load("RankerLib");

Type type = asm.GetType("RankerLib.Ranker");

 

 질의에 사용할 Request 메서드의 리플렉션 정보인 MethodInfo를 얻어옵니다.

MethodInfo mi = type.GetMethod("Request");

 

 질의에 사용할 인자를 object 배열로 만듭니다.

object[] objs = new object[1]{query};

 

 Request 메서드의 리플렉션 정보 개체를 이용하여 실행합니다.

List<RankedUrl> rlist = mi.Invoke(null, objs) as List<RankedUrl>;

 

 얻어온 질의 결과로 ArrayList 개체를 생성하여 이를 반환합니다.

ArrayList ar = new ArrayList(rlist);

return ar;

 

GenericSearch.cs

using System;

using System.Collections.Generic;

using WSE_Core;

using System.Reflection;

using System.Collections;

namespace GenericSearchLib

{

    /// <summary>

    ///검색 서비스를 제공하는 Generic 클래스

    /// </summary>

    public class GenericSearch:MarshalByRefObject

    {

        /// <summary>

        /// 검색 요청 메서드

        /// </summary>

        /// <param name="query">검색 질의</param>

        /// <returns>검색 결과(순위화  페이지 목록)</returns>

        public ArrayList Request(string query)

        {

            Assembly asm = Assembly.Load("RankerLib");

            Type type = asm.GetType("RankerLib.Ranker");

            MethodInfo mi = type.GetMethod("Request");

            object[] objs = new object[1]{query};

            List<RankedUrl> rlist = mi.Invoke(null, objs) as List<RankedUrl>;

            ArrayList ar = new ArrayList(rlist);

            return ar;

        }

    }

}

  

10.2 검색 서비스 서버 만들기

 

 검색 서비스는 윈도우 서비스로 만들게요. Windows 서비스 템플릿 유형의 프로젝트로 SearchSvc 프로젝트를 생성하세요.

 

 설치 관리자를 추가한 후에 서비스 프로세스 인스톨러의 계정을 LocalSystem으로 변경하세요. 그리고 서비스를 시작하는 서비스 이름을 SearchSvc로 바꿉시다. 물론 마법사에 의해 제공하는 Service1.cs 파일도 SearchSvc로 변경하세요.

 

 GenericSearchLib를 참조 추가하고 .NET 리모팅을 위해 System.Runtime.Remoting 어셈블리를 참조 추가합니다.

 

 서비스를 시작하는 OnStart 메서드를 구현합시다. 먼저 Http 채널을 생성하고 이를 등록합니다.

HttpChannel hc = new HttpChannel(10200);

ChannelServices.RegisterChannel(hc, false);

 

 WellKnownObject Single 모드로 GenericSearch 형식을 서비스할 것을 등록합니다. 접근할 명칭은 EHSearchSVC라고 할게요.

RemotingConfiguration.RegisterWellKnownServiceType(

                typeof(GenericSearch),

                "EHSearchSVC",

                WellKnownObjectMode.Singleton

                );

 

 리플렉션을 이용해 서비스를 하는 것이므로 RankerLib 출력 폴더에 있는 파일들을 프로젝트 출력 폴더(일반적으로 Bin 혹은 Debug)에 붙여 놓습니다.

 

 그리고 관리자 권한으로 명령 프롬프트에서 "installutil SearchSvc"를 입력하여 서비스 등록하세요.

 

GenericSearch.cs

using System.ServiceProcess;

using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting;

using GenericSearchLib;

namespace SearchSvc

{

    public partial class SearchSvc : ServiceBase

    {

        public SearchSvc()

        {

            InitializeComponent();

        }

        protected override void OnStart(string[] args)

        {

            HttpChannel hc = new HttpChannel(10200);

            ChannelServices.RegisterChannel(hc, false);

            RemotingConfiguration.RegisterWellKnownServiceType(

                typeof(GenericSearch),

                "EHSearchSVC",

                WellKnownObjectMode.Singleton

                );

        }

        protected override void OnStop()

        {

        }

    }

}

 

 

 

10.3 검색 서비스 확인하기

 

 먼저 관리도구의 서비스를 통해 SearchSvc를 시작하세요.

 

 그리고 검색 서비스를 확인하기 위해 콘솔 응용 프로그램을 생성합니다.

 

 GenericSearchLib를 참조 추가하고 System.Runtime.Remoting 어셈블리를 추가합니다.

 

 코드 작성은 HttpChannel을 생성하고 등록하는 것으로 출발합니다.

HttpChannel hc = new HttpChannel();

ChannelServices.RegisterChannel(hc,false);

 

 Activator의 정적 메서드 GetObject를 호출하여 GenericSearch 개체를 참조합니다.

GenericSearch svc = Activator.GetObject(

                typeof(GenericSearch),

                "http://[서비스 서버 IP 주소]:10200/EHSearchSVC"as GenericSearch;

 

 검색 질의를 받습니다.

Console.WriteLine("검색 질의를 입력하세요.");

string query = Console.ReadLine();

 

 검색 요청하여 결과를 콘솔 화면에 출력합니다.

ArrayList list =  svc.Request(query);

foreach (RankedUrl rurl in list)

{

    Console.WriteLine(rurl);

}

 

Program.cs

using System;

using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels;

using GenericSearchLib;

using WSE_Core;

using System.Collections;

namespace WSESearch_예광탄_Client

{

    class Program

    {

        static void Main(string[] args)

        {

            HttpChannel hc = new HttpChannel();

            ChannelServices.RegisterChannel(hc,false);

             GenericSearch svc = Activator.GetObject(

                typeof(GenericSearch),

                "http:// [서비스 서버 IP 주소:10200/EHSearchSVC"as GenericSearch;

             Console.WriteLine("검색 질의를 입력하세요.");

             string query = Console.ReadLine();

 

             ArrayList list =  svc.Request(query);

             foreach (RankedUrl rurl in list)

             {

                 Console.WriteLine(rurl);

             }

        }

    }

}

 

 

반응형