Running multiple MUC-Services on one Server in ejabberd

In the last few weeks I have been struggling to separate the MUC-Services we provide on our XMPP-Cluster into smaller sub-services. Let’s take the following scenario:

You have a website that users can play games on, and simply chat. So you will have a lot of MUC-Rooms, since (hopefully) you will have a lot of games. But it does not make any sense for the (say) poker players to see all the rooms of the chess-players in a discovery request to the MUC-Service. You you could filter this on the client side but I guess it’s good practice to send as little uninteresting data as possible. Sou you want to separate the MUC-Rooms like this:

  • conference.website.de
  • chess.example.com
  • poker.example.com

People will log in to the server using a domain-name of @website.de (let’s say this is for historical reasons). You will have to set up your ejabberd something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
%% serve all the hosts you need chatservices for
{hosts, ["website.de", "poker.example.com", "chess.example.com"]}.
 
%% configure all COMMON modules, you can make changes to these
%% later, so define everything you need here.
{modules, [
        {mod_adhoc,    []},
        {mod_announce, [{access, announce}]}, 
        {mod_caps,     []},
        {mod_configure,[]},
        {mod_disco,    []},
        {mod_offline,  []},
        {mod_muc_log, [
                       {access_log, muc},
                       {outdir, "/tmp/jabberspool/muc_logs"},
                       {dirtype, subdirs},
                       {timezone, universal}
        ]},
        {mod_stats,    []},
        {mod_time,     []},
        {mod_version,  []}
]}.
 
%% define your MAIN host, this will be the host users log into.
%% you will maybe have some more modules here than in your
%% chat-only hosts
{host_config, "website.de", [{
        %% this loads the common modules, DO NOT FORGET THIS!
        {add, modules},
        [
                %% this will let users see the extra-services in service discovery
                {mod_disco,    [
                                {extra_domains, ["poker.example.com",
                                                        "chess.example.com"]}
                ]},
                {mod_ctlextra, []},
                {mod_http_bind,[]},
                {mod_pubsub,   [
                                {host, "pubsub.@HOST@"},
                                {access_createnode, pubsub_createnode},
                                {plugins, ["flat", "pep"]}
                ]},
                {mod_muc,      [
                                %% THIS HAS TO BE A SUBDOMAIN, THINGS WON'T WORK
                                %% IF YOU JUST USE @HOST@ HERE.
                                {host, "conference.@HOST@"},
                                {access, muc},
                                {access_create, muc},
                                {access_persistent, muc},
                                {access_admin, muc_admin}
                ]},
                {mod_roster,   []},
                {mod_shared_roster,[]},
                {mod_vcard,  []}
        ]
}]}.
 
%% now configure the chat-only hosts
{host_config, "poker.example.com", [{
        {add, modules},
        [
                {mod_muc,      [
                                %% THIS HAS TO BE A SUBDOMAIN, THINGS WON'T WORK
                                %% IF YOU JUST USE @HOST@ HERE.
                                {host, "muc.@HOST@"},
                                {access, muc},
                                {access_create, muc},
                                {access_persistent, muc},
                                {access_admin, muc_admin}
                ]}
        ]
}]}.
 
{host_config, "chess.example.com", [{
        {add, modules},
        [
                {mod_muc,      [
                                %% THIS HAS TO BE A SUBDOMAIN, THINGS WON'T WORK
                                %% IF YOU JUST USE @HOST@ HERE.
                                {host, "muc.@HOST@"},
                                {access, muc},
                                {access_create, muc},
                                {access_persistent, muc},
                                {access_admin, muc_admin}
                ]}
        ]
}]}.

This way everything should work as expected and you should have three MUC-Services running on the same machine. Here is what took me so long to realise how it works:

  • The name of the MUC-Service HAS TO BE different from the name of the host serving it. Otherwise you will run into this.
  • You will need to have the {add, modules} line in every host-config, otherwise the “global” options won’t count
  • Having mod_disco in the common modules is a very good idea. Reconfigure it in your main host to show the other muc-services. Define the HOSTNAME here, not the SERVICENAME.
  • Same goes for the {hosts} directive, HOSTNAME not SERVICENAME

The only drawback I see is that you will have a “subdomain” for each host, and then another subdomain of that for the muc service. But if you name those cleverly it may be not so bad.

Good luck!

Tags: , , ,

Author: steam

Leave a Reply