Re: Communicate with other code from hooks
Shaun Kruger <shaun.kruger <at> gmail.com>
2011-08-01 14:06:45 GMT
There are a few ways of doing this that I like to use. It all depends
on if you have a gen_server per vhost or if you want a global
gen_server. Also, I'm going to make my suggestions based on what I
have seen in the ejabberd 2 series. Things a a little different (and
nicer) in ejabberd3.
The best way of talking to a gen server when you can't just pass a PID
around is by naming your gen server. There are two options for this.
You can create a global (to your node) gen server, or you can start
one for each vhost.
The global gen_server option assuming you are making use of the
gen_mod behaviour.
======================================
start("localhost",Opts) ->
supervisor:start_child(ejabberd_sup,{?MODULE,{?MODULE,start_link,[Opts]},permanent,2000,worker,[?MODULE]}),
ok;
start(Host,Opts) ->
%% Do per vhost startup.
ok.
start_link(Opts) ->
gen_server:start_link({local,?MODULE},?MODULE,Opts,[]).
init(Opts) ->
%% This assumes you simply want opts to be your state variable. I
usually create a local record definition and put opts into it.
{ok,Opts}.
on_register(SID,#jid{lname=Name},Info) ->
gen_server:call(?MODULE,{on_register,Name,SID,Info}),
ok.
In the event you wish to start a gen_server per vhost you can do this:
=======================================
start(Host,Opts) ->
PName = gen_mod:get_module_proc(Host,?MODULE),
supervisor:start_child(ejabberd_sup,{PName,{?MODULE,start_link,[Host,Opts]},permanent,2000,worker,[?MODULE]}),
ok.
start_link(Host,Opts) ->
PName = gen_mod:get_module_proc(Host,?MODULE),
gen_server:start_link({local,PName},?MODULE,{Host,Opts},[]).
init({Host,Opts}) ->
{ok,{Host,Opts}}.
on_register(SID,#jid,{lname=Name,lserver=Host},Info) ->
PName = gen_mod:get_module_proc(Host,?MODULE),
gen_server:call(PName,{on_register,Name,SID,Info}),
ok.
In essence, you must give your gen_server a name that you either can
assume globally (first example), or infer based on the arguments that
come in (second example). Take note that these are only partial
examples. I didn't implement the stop(_Host) function where I stop
the gen_servers and remove them from the supervisor. I have seen some
modules merely start a gen_server or spawn a process without
supervisor support, but I don't recommend it. It's always sad when
your module stops running properly because of a small bug that should
have been automatically corrected.
Shaun
On Mon, Aug 1, 2011 at 12:40 AM, Alexander Kuleshov
<kuleshovmail <at> gmail.com> wrote:
> Hello,
>
> I have hook handler in my code:
>
> ejabberd_hooks:add(sm_register_connection_hook,
> BotState#state.host, ?MODULE, on_register, 80),
>
> on_register(SID, JID, INFO) ->
> {_, _, _, _, Name, _, _} = JID,
> ok.
>
> How can i send message to gen_server for example from this hook with Name?
>
> How can i make know gen_server pid to hook?
>
> Thank you.
> _______________________________________________
> ejabberd mailing list
> ejabberd <at> jabber.ru
> http://lists.jabber.ru/mailman/listinfo/ejabberd
>