[ejabberd] The case for refactoring MUC
Eric Cestari
eric at ohmforce.com
Tue Mar 24 10:40:33 MSK 2009
Hi list,
Here's a proposal for improving mod_muc, and bring it to the
flexibility of mod_pubsub.
Feedback welcome. I'll open a ticket with a patch for review within a
few days.
------------------------------------
= Modular MUC =
== Why ? ==
=== Flexible handler ===
MUC in the unsung hero for developping applications buses. Even more
if they require user interaction.
XEP-0045 sets some base roles for chatting with the default roles and
affiliations.
But using MUC for playing chess (for example) will require different
affiliations and message routing should be flexible given a specific
role.
Jack Moffitt explains the game design of ChessPark (http://
chesspark.com) :
http://metajack.im/2008/11/25/chesspark-design-details-part-3-game-design/
" Another issue is that people watching chess games want to
discuss the moves, potential tactics, and future plans. Players,
however, are not allowed to receive advice or help from anyone, so if
they can see the chat of watchers, then there is a real problem.
We solved this by making roles affect who sees chat messages. In
a chess game room, players can send messages and these messages are
seen by everyone in the room. Regular participants can also talk, but
only other regular participants can see their messages. A player never
sees any chat from an observer during a game. Once a game is over, the
players can see the observers' chat messages. "
ChessPark decided to write its own MUC, Palaver, with twisted, and
custom roles.
But ejabberd's mod_muc already has all the tools to make that happen.
It just lacks the flexibility.
=== Modular storage ===
Default storage is mnesia. But it should be possible to store
persistent rooms using other backends, - RDMSes, Amazon S3 or custom
webservices.
== Architecture ==
Two behaviours are defined :
=== Storage ===
gen_muc_storage : CRUD methods for storing muc. Config is considered
opaque.
muc_storage_default, with a mnesia backend is the default
implementation.
API :
- store_room()
- restore_room()
- forget_room()
- fetch_all_rooms()
That part was easy and done ;)
=== Flexible handler ===
gen_muc_handler : Holds access to configuration. Configuration (the
current #config record) is opaque to mod_muc_room.
Has functions for :
- Room Access control
- Stanza filtering and custom delivery, based on source and
destination role and affiliations
- Discovery processing
- building and processing configuration form
There is a default implementation (following exactly XEP-0045) :
muc_room_default
It should possible for custom handlers to delegate some of their
behaviours to muc_room_default.
As in mod_pubsub, if a function is not implemented in the custom
handler it will be reverted to calling muc_room_default.
Parameters passed are subset of the state :
-record(headers, {room,
host,
server_host,
access,
storage,
config,
affiliations = ?DICT:new(),
subject = "",
subject_author = ""}).
Config, affiliations, subject and subject_author can be modified by
the handler, by returning the modified record.
Upon change of subject and subject_author or affiliation change,
modifications are broadcast to the clients.
API (work in progress) :
- get_default_role(Affiliation,#headers{}) -> Role
- process_message(From, To, Message, #headers{}) ->
{allow, Message, #headers} |
{filter, Message, fun(),#headers} | %fun is called for each
recipient to check for delivery
{deny, Reason, #headers} |
{drop, #headers} |
{error, Error}
- process_presence(From, To, Presence, #headers{}) -> TBD but should
be pretty much like process_message
- process_iq(From, To, XMLNS, #iq, #headers) -> {ok, Reply, #headers}|
{error, Message, #headers}
- get_config(#headers) -> Config (adhoc form)
- set_config(FormResult, #headers) -> ok | {error, Message}
- can_invite(From, #headers) -> true | {false, Message}
- can_join(From, #headers) -> true | {false, Message}
== Configuration ==
{mod_muc, [{storage, s3_muc_storage},{s3_bucket, "chessgame"},
{handler, chessgame},
{host, "chess. at HOST@"},
{access, subscriber},
{access_create, paying_subscriber},
{access_persistent, paying_subscriber},
{access_admin, chess_admin}]}
More information about the ejabberd
mailing list