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

CGS cgsmcmlxxv at gmail.com
Fri Nov 18 14:12:39 MSK 2011


Oh, just delete send_message/1 from exports. I used that to discuss with 
another application. I removed it from module, but I forgot to remove it 
from exports. Sorry.

CGS



On 11/18/2011 12:07 PM, CGS 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/
>>>>>
>>>>
>>>
>>
>>
>



More information about the ejabberd mailing list