[ejabberd] Clustering, data (state) sharing, and hooks firing on the cluster / nodes

Hisham Mardam Bey hisham.mardambey at gmail.com
Sun Nov 20 08:03:35 MSK 2011


At this point I am trying to either use mod_roster:get_user_roster/3
or call into mnesia myself. get_user_roster seems perfect but I do not
know how to get from filter_packet/1's input to the {User,Server}
tuple that is expected on both techniques I mentioned.

hisham.

On Sat, Nov 19, 2011 at 5:33 AM, CGS <cgsmcmlxxv at gmail.com> wrote:
> One way is using ejabberdctl command. Another is to to put Ejabberd in the
> standard Erlang path and to access directly its modules. I used both and I
> had good results. I never entered Mnesia to manipulate the roster. Check
> also mod_roster (if I remember well the name) for details.
>
> If you need more help, let me know, I will check my previous work and I can
> give you some examples of code.
>
> CGS
>
>
>
> On 11/19/2011 06:44 AM, Hisham Mardam Bey wrote:
>>
>> Should I directly query and modify the rosters via mnesia queries or
>> is there an API?
>>
>> On Sat, Nov 19, 2011 at 12:26 AM, Hisham Mardam Bey
>> <hisham.mardambey at gmail.com>  wrote:
>>>
>>> Thanks for your example. Between that and using the roster I have
>>> everything we need except being able to filter basic roster
>>> (subscription) and presence stanzas. I can identify them in the filter
>>> module but haven't found ejabberd's API for manipulating users'
>>> rosters. Once I have that we'll be able to toss out what we currently
>>> have (Red5) and replace it with ejabberd! (=
>>>
>>> hmb.
>>>
>>> On Fri, Nov 18, 2011 at 6:07 AM, CGS<cgsmcmlxxv at gmail.com>  wrote:
>>>>
>>>> Hi, Hisham,
>>>>
>>>> I suppose the hooks you are interested in are:
>>>>
>>>> ejabberd_hooks:add(sm_register_connection_hook, Host,<hook module name>,
>>>> <hook function name>, 90)
>>>> ejabberd_hooks:add(sm_remove_connection_hook, Host,<hook module name>,
>>>> <hook function name>, 90)
>>>>
>>>> Here is an example I wrote some time ago (people didn't want my module,
>>>> so,
>>>> I didn't push further):
>>>>
>>>> --- code snippet ---
>>>>
>>>> -module(mod_filter_presence).
>>>> -author('CGSMCMLXXV<cgsmcmlxxv at gmail.com>').
>>>>
>>>> -behavior(gen_mod).
>>>>
>>>> -include("ejabberd.hrl").
>>>> -include("jlib.hrl").
>>>>
>>>> -export([start/2,
>>>>         stop/1,
>>>>         user_presence/1,
>>>>         user_presence/2,
>>>>         user_presence/3,
>>>>         user_presence/4,
>>>>         send_message/1]).
>>>>
>>>> start(Host, _Opts) ->
>>>>    ?INFO_MSG("mod_filter_presence starting", []),
>>>>    ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE,
>>>> user_presence, 90),
>>>>    ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE,
>>>> user_presence, 90),
>>>>    ok.
>>>>
>>>> stop(Host) ->
>>>>    ?INFO_MSG("mod_filter_presence stopping", []),
>>>>    ejabberd_hooks:delete(sm_register_connection_hook, Host, ?MODULE,
>>>> user_presence, 90),
>>>>    ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE,
>>>> user_presence, 90),
>>>>    ok.
>>>>
>>>> user_presence(JID) ->
>>>>    User = JID#jid.luser,
>>>>    Host = JID#jid.lserver,
>>>>    Resource = JID#jid.lresource,
>>>>    _Data = {},
>>>>    user_presence(User,Host,Resource,_Data).
>>>>
>>>> user_presence(_, JID) ->
>>>>    User = JID#jid.luser,
>>>>    Host = JID#jid.lserver,
>>>>    Resource = JID#jid.lresource,
>>>>    _Data = {},
>>>>    user_presence(User,Host,Resource,_Data).
>>>>
>>>> user_presence(_, JID, _Data) ->
>>>>    User = JID#jid.luser,
>>>>    Host = JID#jid.lserver,
>>>>    Resource = JID#jid.lresource,
>>>>    user_presence(User,Host,Resource,_Data).
>>>>
>>>> user_presence(User, Server, Resource, _Packet) ->
>>>>   %% Do something with "User" from "Server" who tries to log in
>>>>   %% with XMPP-client "Resources" and if it's not enough, I may
>>>>   %% get lucky and have the full "Packet"
>>>>   %% Here should go your code defining FilterIt (filter it) as boolean:
>>>>   %% ->  if FilterIt is true then don't allow connection
>>>>   %% ->  if FilterIt is false then allow connection
>>>>   if (FilterIt == true) ->
>>>>   %% each user has a registered process which can be caught with
>>>>          SID = ejabberd_sm:get_session_pid(User, Server, Resource),
>>>>          SID ! system_shutdown; %% a trick to disconnect the user
>>>>       (FilterIt /= true) ->  ok %% let the user log in
>>>>    end,
>>>>    none.
>>>>
>>>> --- end of code snippet ---
>>>>
>>>> I did that module to filter for a certain resource (XMPP-client software
>>>> ID
>>>> like Pidgin, Psi, Vacuum-IM, Real-time Ignite Spark or whatever), but I
>>>> cut
>>>> that part for you to use it as you think it's fit for your project. You
>>>> need
>>>> just to set the value for FilterIt before enters if-condition. I hope it
>>>> will help. Good luck!
>>>>
>>>> Cheers,
>>>> CGS
>>>>
>>>>
>>>>
>>>>
>>>> On 11/18/2011 09:01 AM, Hisham Mardam Bey wrote:
>>>>>
>>>>> Hi Peter,
>>>>>
>>>>> Although that is a valid solution it will not work for us. We can not
>>>>> rely on our clients having this switched on as our chat service is
>>>>> paid and we need to be in control of who can send messages. This is
>>>>> why we want to block everything by default (yet allow roster requests
>>>>> to travel through) and only let 2 people chat once they have added one
>>>>> another to the roster (this will be subject to our business rules via
>>>>> a packet filter).
>>>>>
>>>>> Now we could try to inspect every message and do the roster check in
>>>>> the packet filter inside of ejabberd but we're trying to avoid having
>>>>> to do that if possible.
>>>>>
>>>>> hisham.
>>>>>
>>>>> On Fri, Nov 18, 2011 at 1:27 AM, Peter Viskup<skupko.sk at gmail.com>
>>>>>  wrote:
>>>>>>
>>>>>> Hi Hisham,
>>>>>> this can be done on XMPP client side. For example Gajim has option
>>>>>> 'Ignore
>>>>>> events from contact not in the roster' in advanced settings.
>>>>>>
>>>>>> Best regards,
>>>>>> --
>>>>>> Peter
>>>>>>
>>>>>> On 11/18/2011 05:42 AM, Hisham Mardam Bey wrote:
>>>>>>>
>>>>>>> A quick update on my findings after doing some more spec reading.
>>>>>>>
>>>>>>> Using rosters and presence I can simulate the exact environment and
>>>>>>> online / offline notifications that we need for our business logic.
>>>>>>> The only rule I still have to meet is blocking all communication by
>>>>>>> default (messages) unless 2 members have successfully subscribed to
>>>>>>> each others rosters. Any hints?
>>>>>>>
>>>>>>> hisham.
>>>>>>>
>>>>>>> On Thu, Nov 17, 2011 at 1:06 PM, Hisham Mardam Bey
>>>>>>> <hisham.mardambey at gmail.com>      wrote:
>>>>>>>>
>>>>>>>> Hi folks,
>>>>>>>>
>>>>>>>> I'm fairly new to ejabberd and Erlang (3rd day using it as of
>>>>>>>> writing
>>>>>>>> this email) and I am having fantastic results with both so far. We
>>>>>>>> want to use ejabberd where I work (dating site, we have up to around
>>>>>>>> 8K people online wanting to chat). What we have so far is ejabberd
>>>>>>>> 2.1.6-2.1 (via apt) coupled with Strophe JS for the web browsers.
>>>>>>>> We've written a couple of Erlang modules that update our system via
>>>>>>>> presence notifications when people join and leave. We've also got
>>>>>>>> another module that coordinates invitations between users and must
>>>>>>>> keep some state about who's said "yes" to who's invitation so that
>>>>>>>> subsequent chat messages between the 2 users can go through (other
>>>>>>>> wise the module's packet filter will drop it). The goal is to then
>>>>>>>> use
>>>>>>>> this by adding a hook on fitler_packet and only let through chats
>>>>>>>> that
>>>>>>>> have been approved and "registered" in the system.
>>>>>>>>
>>>>>>>> My question is really about the last part, how one would go about
>>>>>>>> "sharing" such state across the cluster, and how do hooks work in a
>>>>>>>> cluster? I am still reading up on Erlang and ejabberd clustering and
>>>>>>>> how it works.
>>>>>>>>
>>>>>>>> If I have multiple nodes in my cluster with users connected to
>>>>>>>> different nodes what is the recommended way of tracking such
>>>>>>>> invitation state? Also, if I use presence to figure out when a user
>>>>>>>> has left through a hook, will the presence hook fire only on the
>>>>>>>> node
>>>>>>>> the user was connected to and left (presence changed)?
>>>>>>>>
>>>>>>>> My plan is to read up some more on how Erlang and ejabberd handles
>>>>>>>> clustering then come back here and update this question. In the mean
>>>>>>>> time, any helpful information or resources explaining how this stuff
>>>>>>>> works are greatly appreciated.
>>>>>>>>
>>>>>>>> hisham.
>>>>>>>>
>>>>>>>> --
>>>>>>>> Hisham Mardam-Bey
>>>>>>>> http://hisham.cc/
>>>>>>>>
>>>>>
>>>> _______________________________________________
>>>> ejabberd mailing list
>>>> ejabberd at jabber.ru
>>>> http://lists.jabber.ru/mailman/listinfo/ejabberd
>>>>
>>>
>>>
>>> --
>>> Hisham Mardam-Bey
>>> http://hisham.cc/
>>>
>>
>>
>
> _______________________________________________
> ejabberd mailing list
> ejabberd at jabber.ru
> http://lists.jabber.ru/mailman/listinfo/ejabberd
>



-- 
Hisham Mardam-Bey
http://hisham.cc/


More information about the ejabberd mailing list