Ejabberd 模块发送确认消息

Posted

技术标签:

【中文标题】Ejabberd 模块发送确认消息【英文标题】:Ejabberd module to send an acknowledge message 【发布时间】:2015-10-05 09:42:26 【问题描述】:

我用来发送消息确认的这个 erlang 代码。使用它时出现错误,错误日志如下所示

我的代码:

-module(mod_ack).
-behaviour(gen_mod).
    
%% public methods for this module
-export([start/2, stop/1]).
-export([on_user_send_packet/3]).

-include("logger.hrl").
-include("ejabberd.hrl").
-include("jlib.hrl").

%%add and remove hook module on startup and close

start(Host, _Opts) ->
    ?INFO_MSG("mod_echo_msg starting", []),
    ejabberd_hooks:add(user_send_packet, Host, ?MODULE, on_user_send_packet, 0),
    ok.

stop(Host) ->
    ?INFO_MSG("mod_echo_msg stopping", []),
    ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, on_user_send_packet, 0),
    ok.

on_user_send_packet(From, To, Packet) ->
        return_message_reciept_to_sender(From, To, Packet),
        Packet.


return_message_reciept_to_sender(From, _To, Packet) ->
    IDS = xml:get_tag_attr_s("id", Packet),
    ReturnRecieptType = "serverreceipt",
%%    ?INFO_MSG("mod_echo_msg - MsgID: ~p To: ~p From: ~p", [IDS, _To, From]),
    send_message(From, From, ReturnRecieptType, IDS, "").


send_message(From, To, TypeStr, IDS, BodyStr) ->
    XmlBody = xmlelement, "message",
           ["type", TypeStr,
        "from", jlib:jid_to_string(From),
        "to", jlib:jid_to_string(To),
        "id", IDS,
           [xmlelement, "body", [],
         [xmlcdata, BodyStr]],
    ejabberd_router:route(From, To, XmlBody).

我已经删除了我使用 on_user_send 钩子但仍然出现错误的模块,也更新了错误日志。

错误日志:

2015-10-06 07:13:45.796 [错误] @ejabberd_hooks:run_fold1:371 function_clause,[xml,get_tag_attr_s,[>,jid,>,>,>,>, >,>],[file,"src/xml.erl",line,210],mod_ack,return_message_reciept_to_sender,3, [file,"src/mod_ack.erl",line,36],mod_ack,on_user_send_packet,4,[file,"src/mod_ack.erl",line,30], ejabberd_hooks,safe_apply,3,[file,"src/ejabberd_hooks.erl",line,385],ejabberd_hooks,run_fold1,4,[file,"src/ejabberd_hooks.erl",line, 368],ejabberd_c2s,session_established2,2,[file,"src/ejabberd_c2s.erl",line,1296],p1_fsm,handle_msg,10,[file,"src/p1_fsm.erl ",line,582],proc_lib,init_p_do_apply,3,[file,"proc_lib.erl",line,237]]

【问题讨论】:

【参考方案1】:

你似乎有一个模块干扰 (mod_send_receipt) 或者你有更多的代码注册钩子。您的模块称为mod_ack,它不是导致崩溃的模块。发生崩溃是因为您注册了一个挂钩来运行函数mod_send_receipt:on_user_send_packet,它是“undef”:这意味着它不存在或未导出。

【讨论】:

【参考方案2】:

ejabberd docs 将 user_send_packet 挂钩定义为 arity-4 函数:

user_send_packet(Packet, C2SState, From, To) -> Packet

您正在注册一个 arity-3 函数,因此当 ejabberd 尝试调用您的 on_user_send_packet 函数时,它会传递 4 个参数并获得 undef 函数异常。

为了真正调用您的回调函数,您需要将其参数列表与 ejabberd 将发送的内容相匹配,即:

on_user_send_packet(Packet, _C2SState, From, To)

【讨论】:

以上是关于Ejabberd 模块发送确认消息的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ejabberd 中过滤消息

用erlang解析ejabberd数据包

ejabberd 不将未确认的消息存储到离线存储

如何记录通过 ejabberd 的消息

ejabberd源码分析及开发系列 router模块分析

Strophe & Ejabberd:发送消息后重新认证的问题