列印] 【IT168知識庫】
目標:輸入一個關鍵字,從不同的資產庫裡檢索出合格資源條目。其中,資產庫有本地硬碟上的資料,有遠程web上的資料,其中前一種資源搜尋由應用程式LocalSearcher來做,後一種資源的搜尋由RemWebSearcher來做,而搜尋的入口是一個網站DSearchWeb。DSearchWeb收到搜尋請求後,分別起兩個線程去調用LocalSearcher和RemWebSearcher,等它們兩個的執行結果都回來後把結果組合到一起顯示給客戶,其中由於RemWebSearcher工作壓力比較大,他和DSearchWeb不在一台機器上,它們之間靠Rmoting通訊。實際應用中RemWebSearcher可以有多台來均衡搜尋的壓力,並且如果某台伺服器搜尋逾時或者拋出異常,主入口程式不能崩潰。還有就是我們講分布式搜尋的結果拿到手後需要對結果進行一些排序或者敏感詞過濾的操作。
其中本地搜尋和遠程搜尋都唯寫了一些範例程式碼,本來應該用WebRequest和lucene來完善這塊兒代碼的,後來覺得和本文主題離的有些遠就省略了先。
先來定義相關介面和公用類
/// <summary>
/// 搜尋結果類,為了可以用Remoting傳輸,標記為可序列化
/// </summary>
[Serializable]
public class SearchResult
{
public SearchResult( string rst)
{
result = rst;
}
string result;
public string Result
{
get { return result; }
set { result = value; }
}
}
/// <summary>
/// 搜尋器介面
/// </summary>
public interface ISearcher
{
List < SearchResult > Search( string keyword);
}
然後準備一個本地的搜尋器和遠端搜尋器
/// <summary>
/// 本地搜尋器
/// </summary>
public class LocalSearcher :ISearcher
{
#region ISearcher 成員
public List < SearchResult > Search( string keyword)
{
// 類比用lucene搜尋本地索引
List < SearchResult > list = new List < SearchResult > ();
list.Add( new SearchResult( " 秋天不會來 " ));
// Thread.Sleep(1000);
list.Add( new SearchResult( " 風煙滾滾唱英雄 " ));
// Thread.Sleep(1000);
list.Add( new SearchResult( " 紅藕香殘玉簟秋 " ));
return list;
}
#endregion
}
遠程搜尋伺服器為一個控制台程式,下面是其主要類
/// <summary>
/// 遠程搜尋類,為了讓remoting暴露,繼承MarshalByRefObject
/// </summary>
public class RemWebSearcher : MarshalByRefObject,ISearcher
{
#region ISearcher 成員
public List < SearchResult > Search( string keyword)
{
// 類比用webrequest來抓取網頁,並找出合格結果條目
List < SearchResult > list = new List < SearchResult > ();
list.Add( new SearchResult( " 我是一條小青龍,小青龍 " ));
// Thread.Sleep(1000);
list.Add( new SearchResult( " 相見時難別亦難,東風無力白花殘。 " ));
// Thread.Sleep(1000);
list.Add( new SearchResult( " 為什麼命名相愛,到最後還是要重來。 " ));
return list;
}
#endregion
}
/// <summary>
/// 啟動本台搜尋伺服器,真實環境中遠比這個要複雜
/// </summary>
class Program
{
static void Main( string [] args)
{
TcpChannel channel = new TcpChannel( 8080 );
ChannelServices.RegisterChannel(channel, false );
RemotingConfiguration.RegisterWellKnownServiceType(
typeof (RemWeb.RemWebSearcher),
" RemWebSearcher " , WellKnownObjectMode.Singleton);
Console.WriteLine( " 服務已啟動,斷行符號後停止 " );
Console.Read();
channel.StopListening( null );
ChannelServices.UnregisterChannel(channel);
Console.WriteLine( " 服務已停止,斷行符號後退出 " );
// 這裡要兩個read(),一個不頂事。
Console.Read();
Console.Read();
}
}
接下來,我們做一個網站來讓使用者使用,我們做成ajax的
< form id ="form1" runat ="server" >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< div >
< asp:TextBox ID ="txtKeyword" runat ="server" ></ asp:TextBox >
< asp:Button ID ="btnSearch" runat ="server" Text ="搜尋" OnClick ="btnSearch_Click" />
< asp:UpdateProgress ID ="UpdateProgress1" runat ="server" AssociatedUpdatePanelID ="UpdatePanel1" >
< ProgressTemplate >
Please Wait
</ ProgressTemplate >
</ asp:UpdateProgress >
< br />
< asp:UpdatePanel ID ="UpdatePanel1" runat ="server" UpdateMode ="Conditional" >
< ContentTemplate >
< asp:Repeater ID ="rptResults" runat ="server" >
< ItemTemplate >
< asp:Label runat ="server" ID ="Label1" Text ='<%# Eval("Result") % > ' /> < br />
</ ItemTemplate >
</ asp:Repeater >