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