I stripped mod_last.erl
to test the creation of a IQHandler (pasted only the part that matters):
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,
<<"join">>, ?MODULE, process_local_iq, IQDisc).
stop(Host) ->
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
<<"join">>).
process_local_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 ->
Sec = 60,
IQ#iq{type = result,
sub_el =
[#xmlel{name = <<"query">>,
attrs =
[{<<"xmlns">>, <<"join">>},
{<<"seconds">>,
iolist_to_binary(integer_to_list(Sec))}],
children = []}]}
end.
But when I send the request:
<iq type='get' id='123'>
<query xmlns='join'/>
</iq>
I keep getting the service-unavailable error:
<iq from='alfred@localhost' to='alfred@localhost/Alfreds-MacBook-Pro' type='error' id='123'>
<query xmlns='join'/>
<error code='503' type='cancel'>
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
A similar question wasn't helpful, since I'm not adding to
.
Note: the IQHandler that I want to create is to request joining game rooms.
If you send an IQ stanza without a
to
attribute, the server will "handle the stanza on behalf of the sending entity" (RFC 6120, section 10.3.3). In practice, that means that the server will treat the stanza as if theto
attribute had been the bare JID of the user, in this casealfred@localhost
.When you call
gen_iq_handler:add_iq_handler
to register a new handler, you also specify the "scope", eitherejabberd_local
orejabberd_sm
("SM" stands for "session manager"). If it'sejabberd_local
, the handler will react to IQ stanzas addressed to the server itself, in this caselocalhost
. If it'sejabberd_sm
, the handler will react to IQ stanzas addressed to the bare JID of a local user, e.g.alfred@localhost
.So that's why your IQ stanza ends up not being handled. Either include
to="localhost"
when sending the request, or changeejabberd_local
toejabberd_sm
when registering the handler.