【问题标题】:xmpp ejabberd - query for user presencexmpp ejabberd - 查询用户存在
【发布时间】:2016-01-29 04:13:46
【问题描述】:

如果用户的订阅类型是“两者”,有没有办法在 XMPP 中查询用户存在?

自从我为移动平台构建以来,我已经使用隐私列表阻止了所有传入的存在节。在我的用例中,一个用户至少会订阅 500 个用户,处理这么多的出席信息节会给移动设备带来很大的压力。

因此,我不想处理所有用户节,而是希望仅在查询用户时才获得用户的存在。

【问题讨论】:

    标签: xmpp ejabberd


    【解决方案1】:

    目前 ejabberd 内部没有这样的功能,但这绝对是您可以开发为插件的东西。您可以编写一个插件,该插件将使用 HTTP 网络服务器处理 http 请求,并在响应用户存在之前执行您想要的任何处理和安全检查。

    【讨论】:

      【解决方案2】:

      为了将来的参考,我已经设法收集了一些代码(感谢 mod_last.erl)并构建了一个可以让您查询用户存在的模块。建议和反馈将不胜感激。

      -module(mod_query_presence).
      -behaviour(gen_mod).
      
      -export([start/2, stop/1,
          process_sm_iq/3
      ]).
      
      -include("ejabberd.hrl").
      -include("jlib.hrl").
      -include("logger.hrl").
      
      -include("mod_privacy.hrl").
      
      -define(NS_QUERY_PRESENCE, <<"jabber:iq:qpresence">>).
      
      start(Host, Opts) ->
          IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                                   one_queue),
          gen_iq_handler:add_iq_handler(ejabberd_sm, Host, 
                                        ?NS_QUERY_PRESENCE, ?MODULE, process_sm_iq, IQDisc),
          ?INFO_MSG("Loading module 'mod_iqtest' v.01", []).
      
      stop(Host) ->
          gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_QUERY_PRESENCE),
          ?INFO_MSG("Stoping module 'mod_iqtest' ", []).
      
      process_sm_iq(From, To,
                    #iq{type = Type, sub_el = SubEl} = IQ) ->
          case Type of
            set ->
                IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
            get ->
                User = To#jid.luser,
                Server = To#jid.lserver,
                Resource = xml:get_tag_attr_s(list_to_binary("resource"), SubEl), 
                {Subscription, _Groups} =
                    ejabberd_hooks:run_fold(roster_get_jid_info, Server,
                                            {none, []}, [User, Server, From]),
                if (Subscription == both) or (Subscription == from) or
                     (From#jid.luser == To#jid.luser) and
                       (From#jid.lserver == To#jid.lserver) ->
                       UserListRecord =
                           ejabberd_hooks:run_fold(privacy_get_user_list, Server,
                                                   #userlist{}, [User, Server]),
                       case ejabberd_hooks:run_fold(privacy_check_packet,
                                                    Server, allow,
                                                    [User, Server, UserListRecord,
                                                     {To, From,
                                                      #xmlel{name = <<"presence">>,
                                                             attrs = [],
                                                             children = []}},
                                                     out])
                           of
                         allow -> get_presence(IQ, SubEl, User, Server, Resource);
                         deny ->
                             IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
                       end;
                   true ->
                       IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
                end
          end.
      
      get_presence(IQ, SubEl, LUser, LServer, LResource) ->
        case ejabberd_sm:get_session_pid(LUser, LServer, LResource) of
              none ->
                  IQ#iq{type = error,
                            sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
              Pid ->
                  {_U, _Resource, Status, StatusText} = ejabberd_c2s:get_presence(Pid),
                  IQ#iq{type = result,
                          sub_el =
                                [#xmlel{name = <<"query">>,
                                    attrs =
                                        [{<<"xmlns">>, ?NS_QUERY_PRESENCE},
                                         {<<"status">>, Status},
                                         {<<"StatusText">>, StatusText}],
                                         children = []}]}
          end.
      

      IQ 请求格式

      <iq id='id' to='56876c654366178e0e75a8cd@192.168.1.150' type='get'>
          <query xmlns='jabber:iq:qpresence' resource='Smack'/>
      </iq>
      

      用户在线时的IQ回复格式

      <iq from='56876c654366178e0e75a8cd@192.168.1.150' to='56876c654366178e0e75a8cd@192.168.1.150/Smack' id='last1' type='result'>
          <query xmlns='jabber:iq:qpresence' status='dnd' StatusText='YO'/>
      </iq>
      

      如果用户不在线,你会得到一个服务不可用的错误。

      【讨论】:

        猜你喜欢
        • 2013-04-04
        • 1970-01-01
        • 2020-06-22
        • 2021-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-06
        • 2014-09-19
        相关资源
        最近更新 更多