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

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


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/


More information about the ejabberd mailing list