您的位置:首页 > 编程语言 > C#

蛙蛙推荐:用c#实现一个简单的分布式搜索

2007-07-22 00:21 726 查看
目标:输入一个关键字,从不同的资源库里检索出符合条件的资源条目。其中,资源库有本地硬盘上的数据,有远程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>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>

还有,我们要连接远程的搜索服务器

/// <summary>
/// 在应用程序启动时创建到各搜索服务器的连接,关闭是注销相关通道
/// </summary>
public class Global : System.Web.HttpApplication
{

TcpChannel channel;
protected void Application_Start(object sender, EventArgs e)
{
channel = new TcpChannel();
ChannelServices.RegisterChannel(channel,false);

}

protected void Application_End(object sender, EventArgs e)
{
channel.StopListening(null);
ChannelServices.UnregisterChannel(channel);
}
}


剩下的就是分布式搜索的逻辑了

public class StateObj

public partial class _Default : System.Web.UI.Page

相关链接:
NET多线程同步和互斥机制初探
http://www.cnblogs.com/herony420/articles/221523.html
使用线程池
http://www.cnblogs.com/three/archive/2006/10/11/526082.html
如何对制造者线程和使用者线程进行同步
http://www.cnblogs.com/three/archive/2006/09/29/518519.html
如何:创建和终止线程
http://www.cnblogs.com/three/archive/2006/09/30/519034.html
HOW TO:使用 Visual C# .NET 同步对多线程环境中共享资源的访问
http://support.microsoft.com/kb/816161/zh-cn
@@@@C#线程池的并发问题,高手进@@@@
http://www.ttscj.cn/info/60172.htm
Visual C#中的多线程编程
http://www.manbu.net/article.asp?id=39
WaitHandle.WaitOne Method (TimeSpan, Boolean)
http://msdn2.microsoft.com/en-us/library/85bbbxt9.aspx
Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇
/article/4591721.html

第一次写多线程的帖子,也是初学,可能有好多考虑不全的地方,还请各位老大指正。
相关图片和代码我就贴了。
刚开始贴的代码有些问题,不好意思。

源码下载地址如下,大家自己下载调试吧。

http://files.cnblogs.com/onlytiancai/DSearch.zip
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: