1

我在 ubuntu 14.04 上使用 ejabberd v2.1.11 版本。编译 exmpp 模块并复制到/usr/lib/ejabberd/ebin/位置。以下是“ my_module ”代码。

-module(my_module).

-author("John").

-include("/home/jk/src/exmpp/include/exmpp.hrl").
-include("/home/jk/src/exmpp/include/exmpp_client.hrl").

-include("ejabberd.hrl").

-export([start/2, stop/1]).

-export([on_filter_packet/1]).

-record(state, {}).

stop(_Host) -> ok.

start(Host, Opts) ->
    ?INFO_MSG("START MODULE LOADING", []),
    ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0).
    % gen_server:start_link(?MODULE, [Host], []).

on_filter_packet({From, To, Packet} = Input) ->
    Parser = exmpp_xml:start_parser(), % FAILS HERE
        Schedule = exmpp_xml:parse_final(Parser, "<schedule version='1.0' ></schedule>"),
        exmpp_xml:stop_parser(Parser),
        Input.

当 ejabberd 启动时,抛出以下错误

running hook: {filter_packet,[]}

=ERROR REPORT==== 2015-10-13 22:12:24 ===
E(<0.9790.0>:ejabberd_hooks:335) : {badarg,
                                    [{ets,member,
                                      [exmpp_xml_engines_registry,expat],
                                      []},
                                     {exmpp_xml,is_engine_available,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,520}]},
                                     {exmpp_xml,get_engine_from_options,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,4007}]},
                                     {exmpp_xml,start_parser,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,625}]},
                                     {my_module,on_filter_packet,1,
                                      [{file,"my_module.erl"},{line,52}]},
                                     {ejabberd_hooks,run_fold1,4,
                                      [{file,"ejabberd_hooks.erl"},
                                       {line,331}]},
                                     {ejabberd_router,do_route,3,
                                      [{file,"ejabberd_router.erl"},
                                       {line,315}]},
                                     {ejabberd_router,route,3,
                                      [{file,"ejabberd_router.erl"},
                                       {line,68}]}]}

如何在 ejabberd 模块中使用exmpp模块?

编辑:

在 start 方法中添加exmpp:start()并将 c_src 复制到 ejabberd 库中,它可以工作。

cp -rf exmpp/c_src/ /usr/lib/ejabberd/

我认为由于所有exmpp依赖项都在其自己的模块中,因此将 exmpp_*.beam 文件复制到 ejabberd 模块可以访问的 /usr/lib/ejabberd/ebin/ 位置就足以在 ejabberd 模块中使用,但这不是案子。

尽管上述解决方案有效,但安装 exmpp 模块以便可以在 ejabberd 模块中使用的正确方法是什么。

4

1 回答 1

0

一些模块需要在您使用它们之前进行初始化——它们可能会启动一个长时间运行的进程或创建一个 ETS 表或访问一些远程资源。此外,该模块可能依赖于其他一些模块,并且模块需要在您使用它之前进行初始化,但您不希望将同一个模块初始化两次!OTP“应用程序”(参见http://www.erlang.org/doc/design_principles/des_princ.html)封装了所有这些。

通常,您的目录foo.app中有一个文件ebin,该应用程序文件将描述运行时在运行您的应用程序之前应该初始化哪些应用程序(并且每个应用程序都有自己的应用程序文件......)。

这是我的一个(这实际上是一个 .app.src 模板文件,Rebar3 将其转换为适当的 .app 文件,但依赖部分是相同的):

{application, mdw, [
    {description, "My Doohickey Whatsit"},
    {vsn, "1.0.0"},
    {id, "git"},
    {modules, []},
    {registered, []},
    {applications, [
                  kernel
                 ,stdlib
                 ,mnesia
                 ,ssl
                 ,inets
                 ,lager
                 ,erlcloud
                 ,worker_pool
                 ,wutils
                 ,recon
                 ]},
    {mod, {mdw_app, []}},
    {env, []}
]}.

中的所有applications内容都将在我的应用程序之前初始化。然后,start/2我的mdw_app模块中的方法将被调用。ERTS 将以正确的顺序处理开始的事情,而不是两次开始。

于 2015-10-14T13:05:50.883 回答