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

Hisham Mardam Bey hisham.mardambey at gmail.com
Sat Nov 19 08:44:33 MSK 2011


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/
>



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


More information about the ejabberd mailing list