How to search registered users by name in XMPP ser

2019-04-07 05:19发布

问题:

I'm working on developing chat application in Android with asmack library. I'm using EJABBERD XMPP server. I have done some functionality including login, registration and roster entries etc.,

Now i want to search Registered users from XMPP server to send Buddy request. I googled and tried some codes but still not get succeed.

I'm using the following code, to Search the user from XMPP server.

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();
}

When i execute the above Code. I'm getting the following error in LogCat.

service-unavailable(503)

    at org.jivesoftware.smackx.search.UserSearch.getSearchForm(UserSearch.java:84)

    at org.jivesoftware.smackx.search.UserSearchManager.getSearchForm(UserSearchManager.java:73)

What changes need to be made to make to get the search results?

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,  []}
 ]}.

回答1:

As the default configuration of ejabberd is to keep the search service on vjud.example.com, not search.example.com, you'd need to change this line:

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

to this:

Form searchForm = userSearchManager.getSearchForm("vjud." + connection.getServiceName());


回答2:

A legoscia already explained, your domain of the search service is likely wrong. This would be an explanation for the service-unavailable (503) error. Erstwhilell confused XMPP error codes with HTTP error codes, where 503 typical indicates an overloaded HTTP server. But 503 has a slightly different meaning in the XMPP world: the service is unavailable (for unmentioned/whatever reasons).

Note that Smack contains a convenience method to find the search service (if any): UserSearchManager.getSearchService(). A sound implementation would therefore look something like this:

UserSearchManager usm = …
Collection<String> services = usm.getSearchService();
if (services.isEmtpy())
    throw new Exception("No search services available");
Form searchForm = userSearchManager.getSearchForm(services.iterator().next());
…


回答3:

I just scratched my head so much with the search thing with XMPP. I will assist if you are using ejabberd.

  • First, I use ejabberd with mysql. So I went into the mysql db and found that there are two tables: vcard and vcard_search. So if vcard_search is empty, you will not be able to search. So make sure that your client registers a user's vcard because with this vcard_search will be populated as well as vcard tables.
  • For the client, I use smack 4.1.0 (latest smack library that I consider to be stable). Just use the following code snippet and results will be there. So the trick is to set the answer just once with "user" and jabber user id. Ejabberd does not support "Username".

    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;
    }
    


回答4:

Ejabberd does not support the field value "Username". It is used in openfire. Please use the field vale "user" and pass arguments as string in ejabberd. Thanks. Please Vote up if your error is solved.



回答5:

Please enable module mod_shared_roster and then you can fetch all your users.

For more info please see this All Users in a Shared Roster Group tutorial.



标签: xmpp smack