ejabberd - 模块gen_mod&带有RabbitMq的gen_server

时间:2016-09-07 11:17:39

标签: erlang rabbitmq ejabberd

我目前正在开发一个ejabberd模块,它可以使用带有gen_mod行为的ejabberd钩子直接向RabbitMQ发送队列。队列可以成功发送,没有任何问题。但是,与RabbitMQ服务器的此连接不是持久的。

示例工作代码如下:

-module(mod_rab).
-author('author@domain.com').

-behaviour(gen_mod).

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

-define(PROCNAME, ?MODULE).

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

start(Host, Opts) ->
    ?INFO_MSG("Starting mod_rab testing", [] ),
    register(?PROCNAME,spawn(?MODULE, init, [Host, Opts])),  
    ok.

init(Host, _Opts) ->
    inets:start(),
    ssl:start(),
    ejabberd_hooks:add(set_presence_hook, Host, ?MODULE, send_available_notice, 10),
    ok.

stop(Host) ->
    ?INFO_MSG("Stopping mod_rab testing", [] ),
    ejabberd_hooks:delete(set_presence_hook, Host,
              ?MODULE, send_available_notice, 10),
    ok.

send_available_notice(User, Server, _Resource, _Packet) ->
    {ok, Connection} =
        amqp_connection:start(#amqp_params_network{host = "localhost"}),
    {ok, Channel} = amqp_connection:open_channel(Connection),

    amqp_channel:call(Channel, #'queue.declare'{queue = <<"hello">>}),

    amqp_channel:cast(Channel,
                      #'basic.publish'{
                        exchange = <<"">>,
                        routing_key = <<"hello">>},
                      #amqp_msg{payload = <<"Hello World!">>}),
    io:format(" [x] Sent 'Hello World!'~n"),
    ok = amqp_channel:close(Channel),
    ok = amqp_connection:close(Connection),
    ok.

我尝试使用gen_server创建持久连接,并且应该能够在触发挂钩时使用它。如果我正确理解gen_server,我会保持状态连接并在钩子回调期间使用它。

我之前尝试过的破碎代码:

-module(mod_rab).
-author('author@domain.com').

-behaviour(gen_mod).
-behaviour(gen_server).

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

 -export([start_link/1]).

 -export([handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).


-define(PROCNAME, ?MODULE).

-record(state, {channel, connection}).

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

start_link(Opts) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []).


start(Host, Opts) ->
    ?INFO_MSG("Starting mod_rab testing", [] ),

        inets:start(),
    ssl:start(),

        ejabberd_hooks:add(set_presence_hook, Host, ?MODULE, send_available_notice, 10),

        {ok, Connection} =
                amqp_connection:start(#amqp_params_network{ host = "localhost"),
        {ok, Channel} = amqp_connection:open_channel(Connection),
    ?INFO_MSG("CHANNEL ~s", [Channel] ),
        {ok, #state{ connection = Connection, channel = Channel}},

%%    register(?PROCNAME,spawn(?MODULE, init, [Host, Opts])),
    ok.

init(Host, _Opts) ->

    ok.

stop(Host) ->
    ?INFO_MSG("Stopping mod_rab testing", [] ),

    ejabberd_hooks:delete(set_presence_hook, Host,
              ?MODULE, send_available_notice, 10),
    ok.



send_available_notice(User, Server,_Resource, _Packet) ->
      ?INFO_MSG("HOOK", [] ),

    amqp_channel:call(#state.channel, #'queue.declare'{queue = <<"hello">>}),

    amqp_channel:cast(channel,
                      #'basic.publish'{
                        exchange = <<"">>,
                        routing_key = <<"hello">>},
                      #amqp_msg{payload = <<"Hello World!">>}),
    io:format(" [x] Sent 'Hello World!'~n"),

        ?INFO_MSG("SENT", [] ),

%%      ok = amqp_channel:close(Channel),
%%      ok = amqp_connection:close(Connection),

    ok.

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(send_available_notice, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
            ok.

code_change(_OldVsn, State, _Extra) ->
                {ok, State}.

感谢您的帮助

0 个答案:

没有答案