我在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 lib并运行。
cp -rf exmpp/c_src/ /usr/lib/ejabberd/
我认为,因为所有 exmpp 依赖项都在自己的模块中,将exmpp _ *。beam文件复制到/ usr / lib / ejabberd / ebin / location,ejabberd模块可以访问这些文件就足够了在ejabberd模块中使用,但事实并非如此。
虽然上述解决方案有效,但安装exmpp模块的正确方法是什么,以便可以在ejabberd模块中使用。
答案 0 :(得分:0)
某些模块需要先初始化才能使用它们 - 它们可能会启动一个长时间运行的进程或创建一个ETS表或访问一些远程资源。此外,模块可能依赖于某些其他模块, 模块需要在使用之前进行初始化,但您不希望将同一模块初始化两次! OTP&#34;应用程序&#34; (见http://www.erlang.org/doc/design_principles/des_princ.html)封装了所有这些。
通常,您在foo.app
目录中有一个ebin
文件,此应用文件将描述运行时应在运行应用程序之前初始化的应用程序(并且每个应用程序都会拥有自己的app文件......)。
这是我的一个(这实际上是一个.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将以正确的顺序处理起始事件而不是两次启动。