65.9K
CodeProject 正在变化。 阅读更多。
Home

对等图形 - 搜索

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (5投票s)

2006年1月6日

7分钟阅读

viewsIcon

46423

downloadIcon

390

使用 Microsoft 的 Peer-to-Peer 技术在 Peer Graph 中搜索记录元数据。

背景

Microsoft 的 Peer-to-Peer Graphing 技术为 Windows P2P 应用程序提供了一个稳定、可靠且健壮的通信基础设施。Peer 使用 Peer Name Resolution Protocol (PNRP - 一种无服务器 DNS) 在 Graph 中注册和发现其他 Peer。Graph 是连接 P2P 网络中的 Peer、服务和资源的基石。Peer 可以是用户交互式应用程序、服务或资源。Graphing 允许高效可靠地在 Peer 之间传递数据。

Microsoft 的整个点对点技术通过最新的平台 SDK 以 C/C++ API 调用形式公开。但是,本文中的代码展示了如何使用 C# 从 .NET 托管代码调用这些 API。

引言

本文介绍了在发布到 P2P Graph 的 Peer 记录中搜索元数据的概念。正如我们在前一篇文章中所了解到的,描述所发布对象的内容或目的的元数据附加到每个记录中。Microsoft 将此元数据称为属性。属性表示为格式良好的 XML 片段。

Microsoft 再次决定使用 XML 来表示用于发出搜索请求的标准。Microsoft 提供了一个简单的架构,XML 搜索标准片段必须符合该架构。本文重点介绍了 PeerSearch 类,该类封装了非托管 API 支持的基本搜索功能。

搜索标准架构

搜索标准架构非常简单。根元素必须是 <peersearch>。它支持两种操作:<and><or>。运算符可以嵌套并包含 <clause>。每个 <clause> 都有三个 XML 属性:name、type 和 comparison。name 属性表示属性的名称,type 表示其数据类型。仅支持三种数据类型:intdatestring。支持六种比较类型;等于、大于、小于、不等于、大于等于和小于等于。子句的值指定在开始和结束标签之间。这是一个简单示例

<peersearch>
   <or>
      <clause attrib="peercreatorid" 
              type="string" 
              compare="equal">James *</clause>
      <and>
         <clause attrib="peerlastmodificationtime" 
              type="date" 
              compare="greater">2003-01-31</clause>
         <clause attrib="peerlastmodificationtime" 
              type="date" 
              compare="less">2003-02-28</clause>
      </and>
   </or>
</peersearch>

使用 *? 支持简单的模式匹配。可以使用 \ 字符转义这些字符。

属性的值使用不区分大小写的比较来匹配元数据中的字段。也就是说,attrib="peercreatorid" 匹配元数据 <attribute name="PeerCreatorID" ...>。每个子句的值也不区分大小写。也就是说,<clause ...>James *</clause> 匹配元数据 <attribute>james bond</attribute><attribute>JAMES BROWN</attribute>

typecompare 属性的值是区分大小写的,因为它们来自 XML 架构。当期望日期类型时,必须使用标准的 XML 日期和时间格式。

底层的 Peer Graphing API 保留了以下属性列表。

  • peerlastmodifiedby
  • peercreatorid
  • peerlastmodificationtime
  • peerrecordid
  • peerrecordtype
  • peercreationtime
  • peerlastmodificationtime

虽然记录的元数据不包含这些属性,但仍可在搜索标准中使用这些名称来匹配 PEER_RECORD 对象的相应属性。在此处可以找到有关 PEER_RECORD 的更多信息:PEER_RECORD 对象。

示例代码中包含的 SearchCriteria.xsd 文件包含用于 XML 搜索标准的架构。它从描述“记录搜索查询格式”的 MSDN 库网页中复制而来。此架构用于下面描述的 Validate 方法。记录搜索查询格式

创建搜索对象

已向 PeerGraph 类添加了一个新的 CreateSearch 方法,该方法支持创建新的搜索对象。默认情况下,返回新的 PeerSearch 类实例。您可以重写虚拟 OnCreateSearch 方法以返回您自己的、更好的搜索对象,因为默认对象非常基础。

public PeerSearch CreateSearch()
{
  return OnCreateSearch();
}

protected virtual PeerSearch OnCreateSearch()
{
  return new PeerSearch(this);
}

PeerSearch 构造函数接受一个 Graph 参数,该参数是要执行搜索的 PeerGraph

PeerSearch 类

PeerSearch 类包含一个 Xml 属性,用于设置用于搜索的 XML 搜索标准片段。该类还重写了 ToString 方法以返回 XML 搜索标准片段。其余两个方法将在以下各节中介绍。

Search 方法

Search 方法是 virtual 的,因此可以重写。其默认实现调用 PeerGraph 的一个 internal 方法来执行搜索。

public virtual PeerRecordCollection Search()
{
  return Graph.Search(xml);
}

internal PeerGraph 方法调用底层的 PeerGraphSearchRecords API。如果搜索有效,结果将以 PeerRecordCollection 集合的形式返回。此集合支持标准的 foreach 枚举。

internal PeerRecordCollection Search(string Criteria)
{
  IntPtr hPeerEnum;
  uint hr = PeerGraphNative.PeerGraphSearchRecords(hGraph, 
                                 Criteria, out hPeerEnum);
  if (hr != 0) throw new PeerGraphException(hr);

  return new PeerRecordCollection(hGraph, hPeerEnum);
}

Validate 方法

示例文件 SearchCriteria.xsd 包含用于验证 XML 搜索标准片段的架构,并作为嵌入式资源存储在示例应用程序中。此架构被加载并编译为 PeerSearch 类的 static (共享) 字段。Validate 方法使用该架构来验证当前存储的 XML 片段。

public bool Validate()
{
  XmlValidatingReader vr = new XmlValidatingReader(Xml, 
                               XmlNodeType.Element, null);
  vr.Schemas.Add(schema,null);
  bool valid;
  try
  {
    while (vr.Read()) { }
    valid = true;
  }
  catch (XmlSchemaException ex)
  {
    valid = false;
  }
  catch (XmlException ex)
  {
    valid = false;
  }
  return valid;
}

如果 XML 片段与架构匹配,Validate 方法将返回 true,否则,如果引发异常,则返回 false。通常无需验证 XML 片段,但出于完整性考虑,已包含此功能。

使用示例应用程序

示例应用程序允许您首先使用初始标识创建一个 Graph(非安全 Peer 名称 0.SearchSharedFiles)。第一个实例应使用此标识打开。它将暂停几秒钟以查找其他实例,然后开始侦听。每个后续应用程序实例都应使用不同的标识打开 Graph。这些实例将连接到最近的 Peer 并进行同步。应用程序的每个实例都是一个 Peer。

在“共享”选项卡上,使用“添加文件夹”按钮选择一个包含文件的文件夹。选择文件夹后,文件夹中的每个文件都将作为记录发布到 Graph。请注意,记录设置为在 1 分钟后过期。记录的属性设置为 FileInfo 类的属性。单击列表框中的文件名可在右侧文本框中显示与记录关联的 XML 属性。下面的列表显示了所有操作和传入事件的诊断日志。双击以清除列表。

在“搜索”选项卡上,输入 XML 搜索标准片段。源代码和演示包含一个名为 Search Criteria XML Examples.txt 的文件,其中包含一些方便的 XML 搜索标准片段供您复制并粘贴到示例应用程序中。单击“搜索”按钮以发出搜索。

private void Search_Click(object sender, System.EventArgs e)
{
  if (textBox4.Text.Trim() == string.Empty) return;

  // create the search object and set the criteria
  PeerSearch search = graph.CreateSearch();
  search.Xml = textBox4.Text;

  try
  {
    PeerRecordCollection records = search.Search();
    listBox3.Items.Clear();
    propertyGrid1.SelectedObject = null;

    // enumerate the records and add to the list
    foreach (PeerRecord record in records)
    {
      listBox3.Items.Add(new FileItem(record.DataAsString, record.ID));
    }
  }
  catch (Exception ex)
  {
    System.Windows.Forms.MessageBox.Show(ex.Message, "Search Failed");
  }
}

如果发生错误,将显示一个包含错误代码的弹出对话框。否则,左下方的列表将填充与搜索条件匹配的文件名。单击此列表可在属性网格中显示记录的属性。

关注点

在典型的 P2P 文件共享应用程序中,共享文件是本地资源。有关您正在共享哪些文件的信息不会广播到网络中的每个 Peer。因此,只有通过远程搜索请求,其他 Peer 才能确定您是否拥有匹配搜索条件的 P2P 文件。这种方法的优点是它具有良好的可伸缩性。

相比之下,示例应用程序将有关共享文件的信息发布到 Graph 中的每个 Peer。启动时,每个 Peer 都会与 Graph 同步。同步完成后,每个 Peer 都拥有 Graph 中所有记录的完整副本。因此,搜索仅需在本地执行。但是,这种方法的可伸缩性不佳。

更好的方法是使用两个 Graph。第一个 Graph 是本地的。没有其他 Peer 与其同步,但它包含所有要共享的文件。第二个 Graph 连接到 Internet,Peer 使用此 Graph 发布具有非常短过期时间的搜索请求。收到此请求后,Peer 会针对本地 Graph 执行搜索。任何结果都将通过直接连接返回给发起者。

资源链接

我发现以下资源对于理解对等图形非常有帮助

结论

我希望您发现本文很有用。虽然本文提供了一个基本的搜索类,但也可以提供您自己的类。可以创建一个更好的搜索类,它绕过内置的搜索机制,而是直接枚举记录(这样更快)。这个更好的搜索类可以提供更丰富的类似 SQL 的表达式引擎,支持 INNOTCASEBETWEENLIKE、类型转换和函数(NOWLENSUBSTRINGISDATE 等)。

下一篇文章将重点介绍一个帮助类,该帮助类允许您以更类似 SQL 的方式表达搜索条件,例如

peercreatorid LIKE 'James *' OR (peerlastmodificationtime > 
         CAST('2003-01-31' as date) AND peerlastmodificationtime < 
         CAST('2003-02-28' as date))

而不是

<or>
  <clause attrib="peercreatorid" 
            type="string" 
            compare="equal">James *</clause>
  <and>
    <clause attrib="peerlastmodificationtime" 
            type="date" 
            compare="greater">2003-01-31</clause>
    <clause attrib="peerlastmodificationtime" 
            type="date" 
            compare="less">2003-02-28</clause>
  </and>
</or>

该帮助类提供了将类似 SQL 的搜索表达式转换为所需的 XML 搜索条件格式的方法,反之亦然。

请继续关注以下主题的更多文章

  1. 对等名称解析 - Windows Vista 增强功能
  1. Peer Graph - 搜索标准帮助程序
  2. Peer Graph - 导入和导出数据库
  1. 对等组和身份
  1. 对等协作 - 附近的人
  2. 对等协作 - 端点
  3. 对等协作 - 能力
  4. 对等协作 - 在线状态
  5. 对等协作 - 邀请

如果您对其他主题有建议,请留言。

历史

  • 初始版本。
© . All rights reserved.