Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Smack在XMPP服务器中按名称搜索注册用户?_Xmpp_Smack - Fatal编程技术网

如何使用Smack在XMPP服务器中按名称搜索注册用户?

如何使用Smack在XMPP服务器中按名称搜索注册用户?,xmpp,smack,Xmpp,Smack,我正在用asmack库在Android上开发聊天应用程序。我正在使用EJABBERD XMPP服务器。我已经完成了一些功能,包括登录、注册和名册输入等 现在我想从XMPP服务器搜索注册用户以发送好友请求。我在谷歌上搜索并尝试了一些代码,但仍然没有成功 我使用以下代码从XMPP服务器搜索用户 UserSearchManager userSearchManager = new UserSearchManager(connection); Form searchForm = userSearchMan

我正在用asmack库在Android上开发聊天应用程序。我正在使用EJABBERD XMPP服务器。我已经完成了一些功能,包括登录、注册和名册输入等

现在我想从XMPP服务器搜索注册用户以发送好友请求。我在谷歌上搜索并尝试了一些代码,但仍然没有成功

我使用以下代码从XMPP服务器搜索用户

UserSearchManager userSearchManager = new UserSearchManager(connection);
Form searchForm = userSearchManager.getSearchForm("search." + connection.getServiceName());
Form answerForm = searchForm.createAnswerForm();
answerForm.setAnswer("Name", true);
answerForm.setAnswer("search", "test"); // here i'm passsing the Text value to search

ReportedData resultData;
resultData = userSearchManager.getSearchResults(answerForm, "search."+ connection.getServiceName());

Iterator<Row> it = resultData.getRows();
Row row = null;
while (it.hasNext()) {
    String value = it.next().toString();
    Log.i("Iteartor values......", " " + value);
    System.out.println("Jabber_id :" + row.getValues("jid").next().toString());
    System.out.println("Name :" + row.getValues("Name").next().toString());
    row = it.next();
}
要获得搜索结果,需要进行哪些更改

ejabberd.cfg

%%%   =======
%%%   MODULES

%%
%% Modules enabled in all ejabberd virtual hosts.
%%
{modules,
 [
  {mod_adhoc,    []},
  {mod_announce, [{access, announce}]}, % requires mod_adhoc
  {mod_caps,     []},
  {mod_configure,[]}, % requires mod_adhoc
  {mod_admin_extra, []},
  {mod_disco,    []},
  %%{mod_echo,   [{host, "echo.localhost"}]},
  {mod_irc,      []},
  %% NOTE that mod_http_fileserver must also be enabled in the
  %% "request_handlers" clause of the "ejabberd_http" listener
  %% configuration (see the "LISTENING PORTS" section above).
  %%{mod_http_fileserver, [
  %%                       {docroot, "/var/www"}, 
  %%                       {accesslog, "/var/log/ejabberd/access.log"}
  %%                      ]},
  {mod_last,     []},
  {mod_muc,      [
          %%{host, "conference.@HOST@"},
          {access, muc},
          {access_create, muc},
          {access_persistent, muc},
          {access_admin, muc_admin},
          {max_users, 500}
         ]},
  %%{mod_muc_log,[]},
  {mod_offline,  [{access_max_user_messages, max_user_offline_messages}]},
  {mod_privacy,  []},
  {mod_private,  []},
  {mod_proxy65,  [
          {access, local},
          {shaper, c2s_shaper}
         ]},
  {mod_pubsub,   [ % requires mod_caps
          {access_createnode, pubsub_createnode},
          {pep_sendlast_offline, false},
          {last_item_cache, false},
          %%{plugins, ["default", "pep"]}
          {plugins, ["flat", "hometree", "pep"]}  % pep requires mod_caps
         ]},
  {mod_register, [
          %%
          %% After successful registration, the user receives
          %% a message with this subject and body.
          %%
          {welcome_message, {"Welcome!",
                     "Welcome to a Jabber service powered by Debian. "
                     "For information about Jabber visit "
                     "http://www.jabber.org"}},
          %% Replace it with 'none' if you don't want to send such message:
          %%{welcome_message, none},

          %%
          %% When a user registers, send a notification to
          %% these Jabber accounts.
          %%
          %%{registration_watchers, ["admin1@example.org"]},

          {access, register}
         ]},
  {mod_roster,   []},
  %%{mod_service_log,[]},
  %%{mod_shared_roster,[]},
  {mod_stats,    []},
  {mod_time,     []},
  {mod_vcard,    []},
  {mod_version,  []}
 ]}.

由于ejabberd的默认配置是将搜索服务保持在
vjud.example.com
,而不是
search.example.com
,因此您需要更改此行:

Form searchForm = userSearchManager.getSearchForm("search." + connection.getServiceName());
为此:

Form searchForm = userSearchManager.getSearchForm("vjud." + connection.getServiceName());
答:您的搜索服务域可能是错误的。这将解释
服务不可用(503)
错误,其中503表示过载的HTTP服务器。但是503在XMPP世界中有一个稍微不同的含义:服务不可用(出于未提及的/任何原因)

请注意,Smack包含一个查找搜索服务(如果有)的方便方法:。因此,一个良好的实现应该是这样的:

UserSearchManager usm = …
Collection<String> services = usm.getSearchService();
if (services.isEmtpy())
    throw new Exception("No search services available");
Form searchForm = userSearchManager.getSearchForm(services.iterator().next());
…
UserSearchManager usm=…
Collection services=usm.getSearchService();
if(services.isEmtpy())
抛出新异常(“没有可用的搜索服务”);
Form searchForm=userSearchManager.getSearchForm(services.iterator().next());
…

Ejabberd不支持字段值“Username”。它用于明火。请使用字段vale“user”并在ejabberd中以字符串形式传递参数。

请启用模块
mod_shared\u花名册
,然后您可以获取所有用户


欲了解更多信息,请参阅本教程。

我对XMPP的搜索功能感到非常头疼。 如果您使用ejabberd,我将提供帮助

  • 首先,我使用ejabberd和mysql。所以我进入mysql数据库,发现有两个表:vcard和vcard_search。因此,如果vcard_search为空,您将无法搜索。因此,请确保您的客户端注册了用户的vcard,因为使用此vcard_搜索将与vcard表一起填充 对于客户端,我使用SMAC4.1.0(最新的SMAK库,我认为它是稳定的)。只要使用下面的代码片段,结果就会出现在那里。因此,诀窍是只使用“user”和jabber用户id设置一次答案。Ejabberd不支持“Username”

    public boolean userExists(XMPPConnection mxmpppcconnection,String jid){
    //ProviderManager.getInstance().addIQProvider(“查询”、“jabber:iq:search”、新用户SearchManager().Provider());
    addIQProvider(“查询”,“jabber:iq:search”,new UserSearch.Provider());
    addIQProvider(“查询”,“jabber:iq:vjud”,newusersearch.Provider());
    UserSearchManager searchManager=新的UserSearchManager(mXMPPConnection);
    试一试{
    List services=searchManager.getSearchServices();
    if(services==null | | services.size()<1)
    返回false;
    for(字符串服务:服务){
    Log.e(“服务”,服务);
    }
    形式搜索形式;
    试一试{
    searchForm=searchManager.getSearchForm(services.get(0));
    Form answerForm=searchForm.createAnswerForm();
    试一试{
    setAnswer(“用户”,jid);
    }捕获(非法状态例外){
    例如printStackTrace();
    返回false;
    }
    //setAnswer(“搜索”,jid);
    报告数据;
    试一试{
    data=searchManager.getSearchResults(answerForm,services.get(0));
    Log.e(“此处\t”,“1”);
    if(data.getRows()!=null){
    List rowList=data.getRows();
    如果(rowList.size()>0){
    Log.e(“此处\t”,“2”);
    返回true;
    }否则
    返回false;
    }
    }catch(smakeException.NoResponseException | xmppeException.XMPPErrorException | smakeException.NotConnectedException e){
    e、 printStackTrace();
    返回false;
    }
    }catch(smakeException.NoResponseException | xmppeException.XMPPErrorException | smakeException.NotConnectedException e){
    e、 printStackTrace();
    返回false;
    }
    }捕获(smakeException.NoResponseException | smakeException.NotConnectedException | xmppeException.xmpperException){
    e、 printStackTrace();
    返回false;
    }
    返回false;
    }
    

503表示服务暂时不可用(忙?)。您检查过服务器目前是否过载了吗?通常,您会通过短暂的延迟和重试来处理此类错误。。也许是越来越多的延误。。并让您的用户知道远程服务器似乎正忙。。然后最终失败。您正在将搜索请求发送到服务器的
search
子域,但是
mod_vcard
的默认配置是使用
vjud
子域。您能提供ejabberd配置的相关部分吗?谢谢@erstwhileii的回复。我重新启动了服务器并再次尝试,但仍然显示相同的错误。除了在xmpp中搜索用户之外,其余的工作都很好。如果服务忙,你能告诉我如何处理吗?那么你可能想调查web服务器日志。感谢@Legocia的回复,抱歉我不熟悉ejabberd,如何将搜索子域更改为vjud。我提供了ejabberd.cfg中的一部分。您能告诉我如何将其设置为vjudsho谢@legossia。在我按照上面的说明操作之后,这个错误被修复了。但是当我执行以下命令时(answerForm.set
UserSearchManager usm = …
Collection<String> services = usm.getSearchService();
if (services.isEmtpy())
    throw new Exception("No search services available");
Form searchForm = userSearchManager.getSearchForm(services.iterator().next());
…
public boolean userExists(XMPPConnection mXMPPConnection, String jid) {
    //ProviderManager.getInstance().addIQProvider("query","jabber:iq:search", new UserSearchManager().Provider());
    ProviderManager.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
    ProviderManager.addIQProvider("query", "jabber:iq:vjud", new UserSearch.Provider());
    UserSearchManager searchManager = new UserSearchManager(mXMPPConnection);
    try {

        List<String> services = searchManager.getSearchServices();
        if (services == null || services.size() < 1)
            return false;
        for (String service : services) {
            Log.e("SERVICE", service);
        }
        Form searchForm;
        try {
            searchForm = searchManager.getSearchForm(services.get(0));
            Form answerForm = searchForm.createAnswerForm();
            try {
                answerForm.setAnswer("user", jid);
            } catch (IllegalStateException ex) {
                ex.printStackTrace();
                return false;
            }
            //answerForm.setAnswer("search", jid);
            ReportedData data;
            try {
                data = searchManager.getSearchResults(answerForm, services.get(0));
                Log.e("HERE\t", "1");
                if (data.getRows() != null) {
                    List<ReportedData.Row> rowList = data.getRows();
                    if (rowList.size() > 0) {
                        Log.e("HERE\t", "2");
                        return true;
                    } else
                        return false;

                }
            } catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException e) {
                e.printStackTrace();
                return false;
            }


        } catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException e) {
            e.printStackTrace();
            return false;
        }

    } catch (SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) {
        e.printStackTrace();
        return false;
    }

    return false;
}