我正在尝试从 ejabberd-17.03 迁移到 ejabberd-18.09。我有这个模块,以便我可以将自定义 iq 节发送到 ejabberd。
-module(mod_test_custom).
%% ====================================================================
%% API functions
%% ====================================================================
-export([start/2, stop/1, process_local_iq/3,depends/2,mod_opt_type/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("xmpp.hrl").
%% ====================================================================
%% Internal functions
%% ====================================================================
-define(NS_IQ_CUSTOM, <<"ns:custom">>).
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_local, Host, ?NS_IQ_CUSTOM, ?MODULE, process_local_iq, IQDisc),
xmpp:register_codec(mod_custom),
?INFO_MSG("Inside mod_test_custom”,[]),
ok.
stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_IQ_CUSTOM),
xmpp:unregister_codec(mod_custom),
ok.
depends(_Host, _Opts)->[{?MODULE,soft}].
mod_opt_type(_Option)->
[].
process_local_iq(From,To,{iq, ID, get, NS, Language, SubElement} = IQ)->
?INFO_MSG("Inside mod_test_custom, IQ is ~p~n ",[IQ]),
?INFO_MSG("Inside mod_test_custom, IQ is ~p~n ",[From]),
?INFO_MSG("Inside mod_test_custom, IQ is ~p~n ",[To]),
{ _,ID , Type, Feature, Lang, {_,_,_,Sub_els} } = IQ,
Type,Lang,ID,Feature,
?INFO_MSG("Inside mod_test_custom, IQ is ~p~n ",[Sub_els]),
Sum = 2+2,
FoundSubEls = list_to_binary(integer_to_list(Sum)),
SubElement,
{iq, ID, result, NS, Language,[{xmlel,<<"query">>,[{<<"xmlns">>,<<"ns:custom">>}],[{xmlel,<<"response">>,[{<<"op">>,<<"sum">>},{<<"val">>,FoundSubEls}],[]}]}]}.
该模块适用于ejabberd-17.03。但是当我将它与 ejabberd-18.09 一起使用时,我收到以下错误:
[info] (tcp|<0.523.0>) Received XML on stream = <<"<iq to='example.com' id='tZU4h-20' type='get'><query xmlns='ns:custom'><abc op='sum'></abc></query></iq><r xmlns='urn:xmpp:sm:3'/>">>
[debug] route:
#iq{id = <<"tZU4h-20">>,type = get,lang = <<"en">>,
from =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
to =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]}],
meta = #{ip => {}}}
[debug] local route:
#iq{id = <<"tZU4h-20">>,type = get,lang = <<"en">>,
from =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
to =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]}],
meta = #{ip => {}}}
[error] failed to process iq:
#iq{id = <<"tZU4h-20">>,type = get,lang = <<"en">>,
from =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
to =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]}],
meta = #{ip => {}}}
Reason = {error,{undef,[{mod_test_custom,process_local_iq,[{iq,<<"tZU4h-20">>,get,<<"en">>,{jid,<<"caLmPSeeWQo">>,<<"example.com">>,<<"Smack">>,<<"caLmPSeeWQo">>,<<"example.com">>,<<"Smack">>},{jid,<<>>,<<"example.com">>,<<>>,<<>>,<<"example.com">>,<<>>},[{response,<<>>,<<>>}],#{ip => {}}}],[]},{gen_iq_handler,process_iq,3,[{file,"src/gen_iq_handler.erl"},{line,132}]},{gen_iq_handler,process_iq,4,[{file,"src/gen_iq_handler.erl"},{line,111}]},{ejabberd_local,route,1,[{file,"src/ejabberd_local.erl"},{line,72}]},{ejabberd_router,do_route,1,[{file,"src/ejabberd_router.erl"},{line,368}]},{ejabberd_router,route,1,[{file,"src/ejabberd_router.erl"},{line,92}]},{ejabberd_c2s,check_privacy_then_route,2,[{file,"src/ejabberd_c2s.erl"},{line,826}]},{xmpp_stream_in,process_authenticated_packet,2,[{file,"src/xmpp_stream_in.erl"},{line,637}]}]}}
[debug] route:
#iq{id = <<"tZU4h-20">>,type = error,lang = <<"en">>,
from =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
to =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]},
#stanza_error{
type = wait,code = 500,by = <<>>,
reason = 'internal-server-error',
text =
[#text{
lang = <<"en">>,
data = <<"Module failed to handle the query">>}],
sub_els = []}],
meta = #{ip => {}}}
[debug] local route:
#iq{id = <<"tZU4h-20">>,type = error,lang = <<"en">>,
from =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
to =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]},
#stanza_error{
type = wait,code = 500,by = <<>>,
reason = 'internal-server-error',
text =
[#text{
lang = <<"en">>,
data = <<"Module failed to handle the query">>}],
sub_els = []}],
meta = #{ip => {}}}
[debug] processing packet to full JID:
#iq{id = <<"tZU4h-20">>,type = error,lang = <<"en">>,
from =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
to =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]},
#stanza_error{
type = wait,code = 500,by = <<>>,
reason = 'internal-server-error',
text =
[#text{
lang = <<"en">>,
data = <<"Module failed to handle the query">>}],
sub_els = []}],
meta = #{ip => {}}}
[debug] sending to process <0.523.0>:
#iq{id = <<"tZU4h-20">>,type = error,lang = <<"en">>,
from =
#jid{
user = <<>>,server = <<"example.com">>,resource = <<>>,luser = <<>>,
lserver = <<"example.com">>,lresource = <<>>},
to =
#jid{
user = <<"caLmPSeeWQo">>,server = <<"example.com">>,
resource = <<"Smack">>,luser = <<"caLmPSeeWQo">>,
lserver = <<"example.com">>,lresource = <<"Smack">>},
sub_els =
[#xmlel{
name = <<"query">>,
attrs = [{<<"xmlns">>,<<"ns:custom">>}],
children =
[#xmlel{
name = <<"abc">>,
attrs = [{<<"op">>,<<"sum">>}],
children = []}]},
#stanza_error{
type = wait,code = 500,by = <<>>,
reason = 'internal-server-error',
text =
[#text{
lang = <<"en">>,
data = <<"Module failed to handle the query">>}],
sub_els = []}],
meta = #{ip => {}}}
[debug] Won't add stanza for caLmPSeeWQo@example.com/Smack to CSI queue
[info] (tcp|<0.523.0>) Send XML on stream = <<"<a h='5' xmlns='urn:xmpp:sm:3'/>">>
[debug] Flushing packets of @example.com from CSI queue of caLmPSeeWQo@example.com/Smack
[info] (tcp|<0.523.0>) Send XML on stream = <<"<iq xml:lang='en' to='caLmPSeeWQo@example.com/Smack' from='example.com' type='error' id='tZU4h-20'><query xmlns='ns:custom'><abc op='sum'/></query><error code='500' type='wait'><internal-server-error xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/><text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>Module failed to handle the query</text></error></iq>">>
[info] (tcp|<0.523.0>) Send XML on stream = <<"<r xmlns='urn:xmpp:sm:3'/>">>
[debug] caLmPSeeWQo@example.com/Smack acknowledged 7 of 7 stanzas
[info] (tcp|<0.523.0>) Received XML on stream = <<"<a xmlns='urn:xmpp:sm:3' h='7'/>">>
我已按照这些步骤注册自定义 iq https://github.com/processone/xmpp/issues/9但仍然没有运气。这是我在 xmpp/specs/xmpp_codec.spec 文件中添加的元素
-xml(response,
#elem{name = <<"query">>,
xmlns = <<"ns:custom">>,
module = mod_custom,
result = {response, '$op','$val'},
attrs = [#attr{name = <<"op">>},
#attr{name = <<"val">>}]}).
我是否遗漏了什么,或者在 ejabberd-18.09 中应该做的方式有什么变化?