首页 > 解决方案 > ejabberd BOSH 搜索一无所获

问题描述

我们正在尝试从 Openfire 切换到 ejabberd XMPP 服务器。我在本地 Windows 10 工作站上安装了带有默认选项的 ejabberd。我设置

  mod_vcard:
    search: true

我使用 ejabberd ReST API 注册了几个用户。我还为这些用户设置了一些vcard值(我的理解是 vcard 条目是 ejabberd 搜索工作所必需的,对吗?)使用 Postman,我可以确认用户“testfouoles”有 vcard:

POST http://localhost:5281/api/get_vcard
Body:
{
      "host": "planetrisk.com",
      "user": "testfouoles",
      "name": "FN"
}

Response:
{
    "content": "Test UnclassifiedFouoLes"
}

除了FN之外,还设置了EMAILNICKNAMENICK电子名片。vcards 似乎区分大小写,所以我设置了小写字母和大写字母变体,因为我不确定搜索使用了哪些变体。我还为N FAMILYN GIVEN设置了 vcard2值。

对于 Openfire,我们使用带有自定义搜索插件的 CandyJs。现在我们继续将它与 ejabberd 一起使用。 出于测试目的,我设置

  mod_vcard:
    search: true
    allow_return_all: true

这样,具有空输入字段的搜索操作会返回所有将一些信息添加到其 vCard 的用户(根据ejabberd 文档)。

我们的 CandyJS 搜索插件向 ejabberd BOSH 监听器发出以下 POST 请求:

Request URL:http://localhost:5443/bosh?b=101
Request Method:POST
Status Code:200 OK
Remote Address:127.0.0.1:5443
...
Request Payload
<body rid='55271928' xmlns='http://jabber.org/protocol/httpbind' sid='5633a7a6184041b173970798227fddadea5e8742'>
  <iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='first'><value/></field>
        <field var='last'><value/></field>
        <field var='nick'><value/></field>
        <field var='email'><value/></field>
        <field var='fn'><value/></field>
      </x>
    </query>
  </iq>
</body>

并且 ejabberd 使用唯一注册用户(除了请求用户)的 vcard 数据进行响应:

<body xmlns='http://jabber.org/protocol/httpbind'>
  <iq xml:lang='en' to='army.dudeFOUO(at)everbridge.mil@planetrisk.com/planetrisk_Candy_b4a02de8' from='vjud.planetrisk.com' type='result' id='search2' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x type='result' xmlns='jabber:x:data'>
        <title>Search Results for vjud.planetrisk.com</title>
        <reported>
          <field var='jid' type='text-single' label='Jabber ID'/>
          <field var='fn' type='text-single' label='Full Name'/>
          <field var='first' type='text-single' label='Name'/>
          <field var='middle' type='text-single' label='Middle Name'/>
          <field var='last' type='text-single' label='Family Name'/>
          <field var='nick' type='text-single' label='Nickname'/>
          <field var='bday' type='text-single' label='Birthday'/>
          <field var='ctry' type='text-single' label='Country'/>
          <field var='locality' type='text-single' label='City'/>
          <field var='email' type='text-single' label='Email'/>
          <field var='orgname' type='text-single' label='Organization Name'/>
          <field var='orgunit' type='text-single' label='Organization Unit'/>
        </reported>
        <item>
          <field var='jid'><value>testfouoles@planetrisk.com</value></field>
          <field var='fn'><value>Test UnclassifiedFouoLes</value></field>
          <field var='last'><value>UnclassifiedFouoLes</value></field>
          <field var='first'><value>Test</value></field>
          <field var='middle'><value/></field>
          <field var='nick'><value>testfouoles</value></field>
          <field var='bday'><value/></field>
          <field var='ctry'><value/></field>
          <field var='locality'><value/></field>
          <field var='email'><value>testfouoles@planetrisk.com</value></field>
          <field var='orgname'><value/></field>
          <field var='orgunit'><value/></field>
        </item>
      </x>
    </query>
  </iq>
</body>

到目前为止一切正常。现在,如果我提交具有非空搜索条件的搜索请求,无论 allow_return_all: true 还是 false,搜索都找不到任何内容:

Request Payload
<body rid='839156118' xmlns='http://jabber.org/protocol/httpbind' sid='39d0d2e120960757f97eeb15488ba6820b509bf7'>
  <iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='first'><value>UnclassifiedFouoLes</value></field>
        <field var='last'><value>UnclassifiedFouoLes</value></field>
        <field var='nick'><value>UnclassifiedFouoLes</value></field>
        <field var='email'><value>UnclassifiedFouoLes</value></field>
        <field var='fn'><value>UnclassifiedFouoLes</value></field>
      </x>
    </query>
  </iq>
</body>

在这里,我尝试搜索“UnclassifiedFouoLes”,这是 N FAMILY 的正确值。我试图搜索正确的电子邮件、昵称等 - 没有任何效果。ejabberd 返回一个空结果。

<body xmlns='http://jabber.org/protocol/httpbind'>
  <iq xml:lang='en' to='army.dudeFOUO(at)everbridge.mil@planetrisk.com/planetrisk_Candy_0d46391c' from='vjud.planetrisk.com' type='result' id='search2' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x type='result' xmlns='jabber:x:data'>
        <title>Search Results for vjud.planetrisk.com</title>
        <reported>
          <field var='jid' type='text-single' label='Jabber ID'/>
          <field var='fn' type='text-single' label='Full Name'/>
          <field var='first' type='text-single' label='Name'/>
          <field var='middle' type='text-single' label='Middle Name'/>
          <field var='last' type='text-single' label='Family Name'/>
          <field var='nick' type='text-single' label='Nickname'/>
          <field var='bday' type='text-single' label='Birthday'/>
          <field var='ctry' type='text-single' label='Country'/>
          <field var='locality' type='text-single' label='City'/>
          <field var='email' type='text-single' label='Email'/>
          <field var='orgname' type='text-single' label='Organization Name'/>
          <field var='orgunit' type='text-single' label='Organization Unit'/>
        </reported>
      </x>
    </query>
    </iq>
  </body>

那么,为什么 ejabberd 不通过正确提供的 (?) 匹配 vcard 值的搜索词找到用户?我究竟做错了什么?

我被困住了。我在Jabber Search上找不到任何其他 ejabberd 文档。我不明白标准 vcard 字段名称如何对应于标准 Jabber 搜索字段名称(或者可能是数据表单字段名称?)。

相同的 CandyJS 搜索插件向 Openfire XMPP 服务器发出非常相似的请求并获得结果。唯一的区别是 Openfire 需要一些非标准添加来搜索请求有效负载以指定在哪些字段中搜索:

<field var='Username'><value>1</value></field>
<field var='Name'><value>1</value></field>
<field var='Email'><value>1</value></field>

Openfire 返回结果

<field var="FORM_TYPE" type="hidden"/>

条款。它有什么线索吗?

我被困住了,真的很感谢为我指出正确的方向。

更新:

实际上,这里是第一个问题:当我们向 XMPP 服务器发送以下搜索请求时

<body rid='839156118' xmlns='http://jabber.org/protocol/httpbind'
sid='39d0d2e120960757f97eeb15488ba6820b509bf7'>
  <iq type='set'id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='first'><value>UnclassifiedFouoLes</value></field>
        <field var='last'><value>UnclassifiedFouoLes</value></field>
        <field var='nick'><value>UnclassifiedFouoLes</value></field>
        <field var='email'><value>UnclassifiedFouoLes</value></field>
        <field var='fn'><value>UnclassifiedFouoLes</value></field>
      </x>
    </query>
 </iq>
</body>

搜索条件是用“OR”还是“AND”组合?我们是否搜索任何字段值('first'、'last'、'nick'、email'、'fn')等于 'UnclassifiedFouoLes' 或所有字段都相等的用户?

更新 2: 我正在尝试<x xmlns='jabber:x:data' type='submit'>从 Postman 向 ejabberd 发送一个简单的请求(一个没有 ):

<body rid='1106091871' xmlns='jabber.org/protocol/httpbind' sid='2afabe5b07c316685e25a2d407617a534ca6b2bb'>
  <iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'><last>UnclassifiedFouoLes</last></query>
  </iq>
</body>

结果始终为空 - 它不返回任何项目。并且有一个用户使用“last”vCard =“UnclassifiedFouoLes”。

为什么?是否需要请求中的“来自”子句?

两个现有的客户可以看到对方并在聊天中交流。但是当我以 client1 身份登录时,抓住 sid 并摆脱它们,将它们插入 Postman 帖子,结果是空的

<body xmlns='http://jabber.org/protocol/httpbind' sid='67c6c7ee389a99e3491bbeab9ab198766ffa5ca8' rid='1287825358'>
    <iq xmlns='jabber:client' type='set' id='search2' to='vjud.planetrisk.com'>
        <query xmlns='jabber:iq:search'>
            <last>UnclassifiedFouoLes</last>
        </query>
    </iq>
</body>

标签: xmppejabberdejabberd-moduleejabberd-api

解决方案


简单类型的搜索(没有<x xmlns="jabber:x:data" type="submit">)以某种方式返回错误。

对于扩展搜索,事实证明,我没有发送

<field type="hidden" var="FORM_TYPE"><value>jabber:iq:search</value></field>

条款。这个遗漏对 Openfire 来说效果很好,ejabberd 需要它。

尽管如此,Openfire 搜索插件提供了我在 ejabberd 中没有找到的便利和效率:它允许聊天客户端显示一个搜索框,然后搜索用户在多个字段中键入的值(搜索功能)。在客户端,您需要发送搜索请求,例如

<body rid='273260412' xmlns='http://jabber.org/protocol/httpbind' sid='961w8ipmo2'>
  <iq type='set' id='search2' to='yourSearchDomain.com' xmlns='jabber:client'>
    <query xmlns='jabber:iq:search'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='search'><value>your_search_term</value></field>
        <field var='Username'><value>1</value></field>
        <field var='Name'><value>1</value></field>
        <field var='Email'><value>1</value></field>
      </x>
    </query>
  </iq>
</body>

Openfire 搜索插件会将此请求解释为执行三个搜索请求的命令:查找匹配的用户Usernameyour_search_term然后查找匹配的用户和Name匹配的用户Email。所有三个搜索结果都将使用逻辑OR进行组合。
客户端只需向 Openfire 发送一个Http 搜索请求,即可your_search_term三个字段中进行搜索。使用 ejabberd,客户端需要发送三个Http 请求......

在 ejabberd 模块中实现类似的功能会很好......


推荐阅读