Ejabberd 自定义 IQ 处理程序:获取功能未实现或服务不可用
Ejabberd custom IQ Handler: getting feature-not-implemented or service-unavailable
我删除了 mod_last.erl
以测试 IQHandler 的创建(只粘贴了重要的部分):
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.
但是当我发送请求时:
<iq type='get' id='123'>
<query xmlns='join'/>
</iq>
我不断收到 服务不可用 错误:
<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 没有帮助,因为我没有添加 to
。
注意:我要创建的IQHandler是请求加入游戏房间。
如果您发送没有 to
属性的 IQ 节,服务器将 "handle the stanza on behalf of the sending entity" (RFC 6120, section 10.3.3)。实际上,这意味着服务器会将节视为 to
属性是用户的纯 JID,在本例中为 alfred@localhost
.
当您调用 gen_iq_handler:add_iq_handler
注册新的处理程序时,您还指定了 "scope",ejabberd_local
或 ejabberd_sm
("SM" 代表 "session manager").如果它是 ejabberd_local
,处理程序将对寻址到服务器本身的 IQ 节做出反应,在本例中为 localhost
。如果它是 ejabberd_sm
,处理程序将对寻址到本地用户的纯 JID 的 IQ 节做出反应,例如alfred@localhost
.
这就是为什么你的 IQ 节最终没有被处理的原因。在发送请求时包含 to="localhost"
,或者在注册处理程序时将 ejabberd_local
更改为 ejabberd_sm
。
我删除了 mod_last.erl
以测试 IQHandler 的创建(只粘贴了重要的部分):
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.
但是当我发送请求时:
<iq type='get' id='123'>
<query xmlns='join'/>
</iq>
我不断收到 服务不可用 错误:
<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 没有帮助,因为我没有添加 to
。
注意:我要创建的IQHandler是请求加入游戏房间。
如果您发送没有 to
属性的 IQ 节,服务器将 "handle the stanza on behalf of the sending entity" (RFC 6120, section 10.3.3)。实际上,这意味着服务器会将节视为 to
属性是用户的纯 JID,在本例中为 alfred@localhost
.
当您调用 gen_iq_handler:add_iq_handler
注册新的处理程序时,您还指定了 "scope",ejabberd_local
或 ejabberd_sm
("SM" 代表 "session manager").如果它是 ejabberd_local
,处理程序将对寻址到服务器本身的 IQ 节做出反应,在本例中为 localhost
。如果它是 ejabberd_sm
,处理程序将对寻址到本地用户的纯 JID 的 IQ 节做出反应,例如alfred@localhost
.
这就是为什么你的 IQ 节最终没有被处理的原因。在发送请求时包含 to="localhost"
,或者在注册处理程序时将 ejabberd_local
更改为 ejabberd_sm
。