11.2.2 구현

WSE Manager 응용은 검색 서비스와 웹 로봇 서비스를 이용합니다. 두 가지 서비스 모두 .NET 리모팅 서비스를 사용하므로 System.Runtime.Remoting 어셈블리를 참조 추가합니다.

그리고 검색 서비스에서 제공하는 MashalByReference 개체를 참조하기 위해 서버와 클라이언트 모두 참조해야 하는 GenericSearchLib 어셈블리를 추가합니다.

웹 로봇 서비스에서 제공하는 개체를 참조하기 위해 GenericWebRobotLib 어셈블리를 참조 추가합니다.

그리고 RankedUrlControlLib 어셈블리와 DBMForAllLib, DBMForSearchLib, WSECore 어셈블리도 참조 추가합니다.

MainForm의 Load 이벤트 핸들러를 추가하세요.

private void MainForm_Load(object sender, EventArgs e)

이벤트 핸들러에서는 .NET 리모팅 서비스를 사용하기 위해 HttpChannel 개체를 생성하여 등록합니다.

HttpChannel hc = new HttpChannel();
ChannelServices.RegisterChannel(hc, false);

웹 로봇의 활성화 상태에 따라 웹 로봇 수집 시작과 멈춤 버튼의 활성화 속성을 설정합니다. 웹 로봇의 MashalByReference 개체를 참조하기 위한 속성은 별도로 만들어서 사용합시다.

bool enable = WebRobot.GetEnabled();
SetStartStopButton(enable);

웹 로봇 서비스의 GenericWebRobot 개체와 검색 서비스의 GenericSearch 개체를 참조하기 위한 속성을 제공합니다.

GenericWebRobot WebRobot
{
    get
    {
        GenericWebRobot robot = Activator.GetObject(
           typeof(GenericWebRobot),
           "http://[웹 로봇 서비스 서버의 IP 주소]:10400/WebRobotSVC")
           as GenericWebRobot;
        return robot;
    }
}

GenericSearch Searcher
{
    get
    {
        GenericSearch searcher = Activator.GetObject(
           typeof(GenericSearch),
           "http://[검색 서비스 서버의 IP 주소]:10200/EHSearchSVC") as GenericSearch;
        return searcher;
    }
}

웹 로봇 수집 멈춤과 시작 버튼 활성화를 설정하는 메서드를 작성하세요.

private void SetStartStopButton(bool enable)
{
    btn_start.Enabled = !enable;
    btn_stop.Enabled = enable;
}

검색 버튼 클릭 이벤트 핸들러를 추가하세요.

private void btn_search_Click(object sender, EventArgs e)

검색 결과를 보여주는 ruc_result의 Clear 메서드를 호출하여 결과를 초기화합니다.

ruc_result.Clear();

쿼리 입력 창의 Text 속성을 입력 인자로 Searcher의 Request 메서드를 호출하여 결과 목록을 얻어와서 ruc_result에 추가합니다.

string query = tbox_query.Text;
ArrayList list = Searcher.Request(query);
foreach (RankedUrl rurl in list)
{
    ruc_result.AddRankedUrl(rurl);
}

검색 결과를 보여주는 ruc_reuslt 컨트롤의 RUClick 이벤트 핸들러를 추가합시다.

private void ruc_result_RUClick(object sender, RUrlClickEventArgs e)

이벤트 핸들러에서는 이벤트 처리 인자의 RankedUrl 개체를 입력 인자로 EHBrowser 폼을 생성하여 활성화합니다. EHBrowser 부분은 EH 응용 만들기에서 작성한 것과 일치합니다.

if (e.RUrl != null)
{
    RankedUrl rurl = e.RUrl;
    EHBrowser eb = new EHBrowser(rurl);
    eb.Show();
}

웹 로봇 수집 시작 버튼과 멈춤 버튼 클릭 이벤트 핸들러를 추가하여 웹 로봇의 수집 여부를 설정합니다.

private void btn_start_Click(object sender, EventArgs e)
{
    WebRobot.SetEnabled(true);
    SetStartStopButton(true);
}

private void btn_stop_Click(object sender, EventArgs e)
{
    WebRobot.SetEnabled(false);
    SetStartStopButton(false);
}

수집 주기 설정 버튼 클릭 이벤트 핸들러와 Seed 사이트 추가 버튼 클릭 이벤트 핸들러를 추가하여 웹 로봇의 설정 주기 및 Seed 사이트 추가 메서드를 호출합니다.

private void btn_set_period_Click(object sender, EventArgs e)
{
    WebRobot.SetPeriod((int)nud_period.Value);
}
private void btn_add_seed_Click(object sender, EventArgs e)
{
    WebRobot.SetSeedSite(tbox_seed_site.Text);
}

수집 대상 목록 새로고침 버튼 클릭 이벤트 핸들러를 추가하세요.

private void btn_refresh_candi_Click(object sender, EventArgs e)

수집 대상 목록 ListView의 항목을 지워줍니다.

lv_candidate.Items.Clear();

EHDbmForAll 정적 클래스를 이용하여 수집 대상 목록을 얻어옵니다.

List<Candidate> list = EHDbmForAll.GetCandidates();

얻어온 목록으로 ListViewItem 개체를 생성하여 수집 대상 목록 ListView에 추가합니다.

foreach (Candidate candi in list)
{
        ListViewItem lvi = new ListViewItem(
            new string[] { candi.Url, candi.Depth.ToString() });
        lv_candidate.Items.Add(lvi);
}

수집 완료 사이트 목록 새로고침 버튼 클릭 이벤트 핸들러를 추가하세요.

private void btn_refresh_purl_Click(object sender, EventArgs e)

수집 완료 사이트 목록을 보여주는 ListView의 항목을 지워줍니다.

lv_posted.Items.Clear();

EHDbmForAll 정적 클래스를 이용하여 수집 완료 사이트 목록을 얻어옵니다.

List<PostedUrl> list = EHDbmForAll.GetPostedUrls();

수집 완료 사이트 목록의 각 PostedUrl 개체로 ListViewItem 개체를 생성하여 수집 완료 사이트 목록에 추가합니다.

foreach (PostedUrl purl in list)
{
        ListViewItem lvi = new ListViewItem(
            new string[] { purl.Url, purl.OriginUrl, purl.Depth.ToString() });
        lv_posted.Items.Add(lvi);
}

모니터링 탭 페이지의 수집 목록 새로고침 버튼의 클릭 이벤트 핸들러를 추가합니다.

private void bnt_refresh_purl2_Click(object sender, EventArgs e)

수집 목록을 보여주는 ListBox 컨트롤의 항목을 지워줍니다.

lbox_posted_page.Items.Clear();

수집 목록을 얻어오는 부분은 DbmForAllLib를 이용해야 할 것 같은데 아직 제공하지 않는 기능입니다. EHDbmForAll 정적 클래스에 GetPostedUrls 메서드 이름으로 수집한 페이지 목록을 제공하는 메서드를 추가하여 이를 이용합시다.

List<PostedUrl> list = EHDbmForAll.GetPostedUrls();

얻어온 수집 목록을 리스트 박스 목록에 추가합니다.

foreach (PostedUrl purl in list)
{
    lbox_posted_page.Items.Add(purl);
}

잠시 DbmForAllLib로 가서 EHDbmForAll 클래스에 GetPostedUrls 메서드를 작성합시다.

public static List<PostedUrl> GetPostedUrls()

결과 목록을 보관할 컬렉션을 생성합니다.

List<PostedUrl> list = new List<PostedUrl>();

PostedUrlTable의 모든 항목을 얻어올 SqlCommand 개체를 만듭니다.

SqlCommand scom = MakeSPCommand("Select  * From PostedUrlTable"
           , CommandType.Text);

SqlCommand 개체의 연결을 개방한 후 명령을 실행합니다.

scom.Connection.Open();
SqlDataReader sdr = scom.ExecuteReader();

명령으로 얻어온 SqlDataReader 개체의 결과로 PostedUrl 개체를 만들어서 결과를 보관할  컬렉션에 추가하고 SqlDataReader 개체를 닫습니다.

while (sdr.Read())
{
    PostedUrl purl = new PostedUrl();
    purl.Url = sdr["Url"].ToString();
    purl.OriginUrl = sdr["OriginUrl"].ToString();
    purl.Depth = (int)sdr["Depth"];
    purl.Title = sdr["Title"].ToString();
    purl.PostedTime = (DateTime)sdr["PostedTime"];
    purl.Content = sdr["PostedContent"].ToString();
    list.Add(purl);
}
sdr.Close();

SqlCommand 개체의 연결을 닫고 결과 목록을 반환합니다.

scom.Connection.Close();
return list;

▷ EHDbmForAll.cs에 추가한 내용(DbmForAllLib)

        /// <summary>
        /// 수집한 사이트 목록 가져오기 메서드
        /// </summary>
        /// <returns>수집한 사이트 목록</returns>
        public static List<PostedUrl> GetPostedUrls()
        {
            List<PostedUrl> list = new List<PostedUrl>();
            SqlCommand scom = MakeSPCommand("Select  * From PostedUrlTable"
               , CommandType.Text);
 
            scom.Connection.Open();
            SqlDataReader sdr = scom.ExecuteReader();
            while (sdr.Read())
            {
                PostedUrl purl = new PostedUrl();
                purl.Url = sdr["Url"].ToString();
                purl.OriginUrl = sdr["OriginUrl"].ToString();
                purl.Depth = (int)sdr["Depth"];
                purl.Title = sdr["Title"].ToString();
                purl.PostedTime = (DateTime)sdr["PostedTime"];
                purl.Content = sdr["PostedContent"].ToString();
                list.Add(purl);
            }
            sdr.Close();
            scom.Connection.Close();
            return list;
        }

수집 목록 선택 변경 이벤트 핸들러를 추가하세요.

private void lbox_posted_page_SelectedIndexChanged(object sender, EventArgs e)

선택 항목이 없으면 핸들러를 종료합니다.

if (lbox_posted_page.SelectedIndex == -1)
{
    return;
}

선택 항목을 PostedUrl 개체 형식으로 참조하여 결과를 보여주는 컬렉션에 추가합니다.

PostedUrl purl = lbox_posted_page.SelectedItem as PostedUrl;
ruc_selected.SetRankedUrl(new RankedUrl(purl, 0));

형태소 목록 새로고침 버튼의 클릭 이벤트 핸들러를 추가하세요.

private void btn_refresh_moph_Click(object sender, EventArgs e)

EHDbmForAll 정적 클래스를 이용하여 형태소 목록을 얻어와서 ListBox의 DataSource 속성을 설정합니다.

List<string> list = EHDbmForAll.GetMorphemes();
lbox_morpheme.DataSource = list;

형태소 목록 선택 변경 이벤트 핸들러를 추가하세요.

private void lbox_morpheme_SelectedIndexChanged(object sender, EventArgs e)

형태소 목록을 보여주는 ListView 컨트롤의 항목을 지워줍니다.

lview_morpheme.Items.Clear();

만약 선택 항목이 없으면 이벤트 핸들러를 종료합니다.

if (lbox_morpheme.SelectedIndex == -1)
{
    return;
}

선택 항목의 이름을 참조합니다.

string mname = lbox_morpheme.SelectedItem as string;

EHDbmForSearch 정정 클래스를 이용하여 역 파일 목록을 얻어옵니다.

List<InvertedElem> list = EHDbmForSearch.GetInvertedFile(mname);

얻어온 정보의 페이지 주소로 형태소 전체 개수를 얻어와서 ListViewItem 개체를 생성하여 ListView 컨트롤의 목록에 추가합니다.

foreach (InvertedElem ie in list)
{
    int tcnt = EHDbmForSearch.GetTotalCountInUrl(ie.Url);
    ListViewItem lvi = new ListViewItem(
        new string[] { ie.Url,ie.RefCount.ToString(),tcnt.ToString() });
    lview_morpheme.Items.Add(lvi);
}

▷ MainForm.cs

using System;
using System.Windows.Forms;
using GenericWebRobotLib;
using GenericSearchLib;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels;
using System.Collections;
using WSE_Core;
using DBM_ForAll;
using System.Collections.Generic;
using DBMForSearchLib;
using RankedUrlControlLib;
 
namespace WSEManager
{
    public partial class MainForm : Form
    {
        GenericWebRobot WebRobot
        {
            get
            {
                GenericWebRobot robot = Activator.GetObject(
                   typeof(GenericWebRobot),
                   "http://[웹 수집 로봇 서버의 IP 주소]:10400/WebRobotSVC")
                   as GenericWebRobot;
                return robot;
            }
        }
 

        GenericSearch Searcher
        {
            get
            {
                GenericSearch searcher = Activator.GetObject(
                   typeof(GenericSearch),
                   "http://[검색 서비스 서버의 IP 주소]:10200/EHSearchSVC")
                    as GenericSearch;
                return searcher;
            }
        }

        public MainForm()
        {
            InitializeComponent();
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            HttpChannel hc = new HttpChannel();
            ChannelServices.RegisterChannel(hc, false);
            bool enable = WebRobot.GetEnabled();
            SetStartStopButton(enable);
        }
 
        private void SetStartStopButton(bool enable)
        {
            btn_start.Enabled = !enable;
            btn_stop.Enabled = enable;
        }


        private void btn_search_Click(object sender, EventArgs e)
        {
            ruc_result.Clear();
 
            string query = tbox_query.Text;
            ArrayList list = Searcher.Request(query);
            foreach (RankedUrl rurl in list)
            {
                ruc_result.AddRankedUrl(rurl);         
                
            }
        }
 
        private void ruc_result_RUClick(object sender, RUrlClickEventArgs e)
        {
            if (e.RUrl != null)
            {
                RankedUrl rurl = e.RUrl;
                EHBrowser eb = new EHBrowser(rurl);
                eb.Show();
            }
        }
 
        private void btn_start_Click(object sender, EventArgs e)
        {
            WebRobot.SetEnabled(true);
            SetStartStopButton(true);
        }
 


        private void btn_stop_Click(object sender, EventArgs e)
        {
            WebRobot.SetEnabled(false);
            SetStartStopButton(false);
        }
  
        private void btn_set_period_Click(object sender, EventArgs e)
        {
            WebRobot.SetPeriod((int)nud_period.Value);
        }
 
        private void btn_add_seed_Click(object sender, EventArgs e)
        {
            WebRobot.SetSeedSite(tbox_seed_site.Text);
        }
 
        private void btn_refresh_candi_Click(object sender, EventArgs e)
        {
            lv_candidate.Items.Clear();
            List<Candidate> list = EHDbmForAll.GetCandidates();
  
            foreach (Candidate candi in list)
            {
                ListViewItem lvi = new ListViewItem(
                    new string[] { candi.Url, candi.Depth.ToString() });
                lv_candidate.Items.Add(lvi);
            }
        }
 


        private void btn_refresh_purl_Click(object sender, EventArgs e)
        {
            lv_posted.Items.Clear();
            List<PostedUrl> list = EHDbmForAll.GetPostedUrls();
            foreach (PostedUrl purl in list)
            {
                ListViewItem lvi = new ListViewItem(
                    new string[] { purl.Url, purl.OriginUrl, purl.Depth.ToString() });
                lv_posted.Items.Add(lvi);
            }
        }
 
        private void bnt_refresh_purl2_Click(object sender, EventArgs e)
        {
            lbox_posted_page.Items.Clear();
            List<PostedUrl> list = EHDbmForAll.GetPostedUrls();
            foreach (PostedUrl purl in list)
            {
                lbox_posted_page.Items.Add(purl);
            }
        }
 
        void lbox_posted_page_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbox_posted_page.SelectedIndex == -1)
            {
                return;
            }
            PostedUrl purl = lbox_posted_page.SelectedItem as PostedUrl;
            ruc_selected.SetRankedUrl(new RankedUrl(purl, 0));
        }
         private void btn_refresh_moph_Click(object sender, EventArgs e)
        {
            List<string> list = EHDbmForAll.GetMorphemes();
            lbox_morpheme.DataSource = list;
        }
 
        void lbox_morpheme_SelectedIndexChanged(object sender, EventArgs e)
        {
            lview_morpheme.Items.Clear();
            if (lbox_morpheme.SelectedIndex == -1)
            {
                return;
            }
            string mname = lbox_morpheme.SelectedItem as string;
            List<InvertedElem> list = EHDbmForSearch.GetInvertedFile(mname);
            foreach (InvertedElem ie in list)
            {
                int tcnt = EHDbmForSearch.GetTotalCountInUrl(ie.Url);
                ListViewItem lvi = new ListViewItem(
                    new string[] { ie.Url,ie.RefCount.ToString(),tcnt.ToString() });
                lview_morpheme.Items.Add(lvi);
            }
        } 
    }
}

EHBrowser 컨트롤의 생성자는 순위화 한 페이지 개체를 입력 인자로 받는 것으로 변경하세요.

public EHBrowser(RankedUrl rurl)

생성자 메서드에서는 마법사에 의해 작성한 InitializeComponent 메서드 호출로 초기 자식 컨트롤 배치 등을 마친 후에 입력 인자로 받은 순위화 한 페이지 개체의 속성으로 자식 컨트롤의 Text속성을 설정합니다. 그리고 페이지 주소를 입력 인자로 WebBrowser 컨트롤인 wb의 Navigate 메서드를 호출합니다.

▷ EHBrowser.cs

using System.Windows.Forms;
using WSE_Core;

namespace WSEManager
{
    public partial class EHBrowser : Form
    {
        public EHBrowser(RankedUrl rurl)
        {
            InitializeComponent();
            lb_addr.Text = rurl.Url;
            lb_title.Text = rurl.PUrl.Title;
            wb.Navigate(rurl.Url);
        }
    }
}

이제 WSA Manager 응용을 빌드하여 테스트 해 보세요.