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

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


>From the irc channel, here' what I said:

(05:45) < CodeWarrior> figured it out, I got what I need with
{jid,User,Server,_,_,_,_} = RosterOwner
(05:46) < CodeWarrior> no jlib or other helper to get this?

On Sun, Nov 20, 2011 at 12:03 AM, Hisham Mardam Bey
<hisham.mardambey at gmail.com> wrote:
> 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/
>



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


More information about the ejabberd mailing list