1
.. index:: XMLStream, BaseXMPP, ClientXMPP, ComponentXMPP
6
The core of SleekXMPP is contained in four classes: ``XMLStream``,
7
``BaseXMPP``, ``ClientXMPP``, and ``ComponentXMPP``. Along side this
8
stack is a library for working with XML objects that eliminates most
9
of the tedium of creating/manipulating XML.
11
.. image:: _static/images/arch_layers.png
18
The Foundation: XMLStream
19
-------------------------
20
:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` is a mostly XMPP-agnostic
21
class whose purpose is to read and write from a bi-directional XML stream.
22
It also allows for callback functions to execute when XML matching given
23
patterns is received; these callbacks are also referred to as :term:`stream
24
handlers <stream handler>`. The class also provides a basic eventing system
25
which can be triggered either manually or on a timed schedule.
29
:class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` instances run using at
30
least three background threads: the send thread, the read thread, and the
31
scheduler thread. The send thread is in charge of monitoring the send queue
32
and writing text to the outgoing XML stream. The read thread pulls text off
33
of the incoming XML stream and stores the results in an event queue. The
34
scheduler thread is used to emit events after a given period of time.
36
Additionally, the main event processing loop may be executed in its
37
own thread if SleekXMPP is being used in the background for another
40
Short-lived threads may also be spawned as requested for threaded
41
:term:`event handlers <event handler>`.
43
How XML Text is Turned into Action
44
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45
To demonstrate the flow of information, let's consider what happens
46
when this bit of XML is received (with an assumed namespace of
51
<message to="user@example.com" from="friend@example.net">
56
1. **Convert XML strings into objects.**
58
Incoming text is parsed and converted into XML objects (using
59
ElementTree) which are then wrapped into what are referred to as
60
:term:`Stanza objects <stanza object>`. The appropriate class for the
61
new object is determined using a map of namespaced element names to
64
Our incoming XML is thus turned into a :class:`~sleekxmpp.stanza.Message`
65
:term:`stanza object` because the namespaced element name
66
``{jabber:client}message`` is associated with the class
67
:class:`~sleekxmpp.stanza.Message`.
69
2. **Match stanza objects to callbacks.**
71
These objects are then compared against the stored patterns associated
72
with the registered callback handlers. For each match, a copy of the
73
:term:`stanza object` is paired with a reference to the handler and
74
placed into the event queue.
76
Our :class:`~sleekxmpp.stanza.Message` object is thus paired with the message stanza handler
77
:meth:`BaseXMPP._handle_message` to create the tuple::
79
('stanza', stanza_obj, handler)
81
3. **Process the event queue.**
83
The event queue is the heart of SleekXMPP. Nearly every action that
84
takes place is first inserted into this queue, whether that be received
85
stanzas, custom events, or scheduled events.
87
When the stanza is pulled out of the event queue with an associated
88
callback, the callback function is executed with the stanza as its only
92
The callback, aka :term:`stream handler`, is executed in the main event
93
processing thread. If the handler blocks, event processing will also
96
4. **Raise Custom Events**
98
Since a :term:`stream handler` shouldn't block, if extensive processing
99
for a stanza is required (such as needing to send and receive an
100
:class:`~sleekxmpp.stanza.Iq` stanza), then custom events must be used.
101
These events are not explicitly tied to the incoming XML stream and may
102
be raised at any time. Importantly, these events may be handled in their
105
When the event is raised, a copy of the stanza is created for each
106
handler registered for the event. In contrast to :term:`stream handlers
107
<stream handler>`, these functions are referred to as :term:`event
108
handlers <event handler>`. Each stanza/handler pair is then put into the
112
It is possible to skip the event queue and process an event immediately
113
by using ``direct=True`` when raising the event.
115
The code for :meth:`BaseXMPP._handle_message` follows this pattern, and
116
raises a ``'message'`` event::
118
self.event('message', msg)
120
The event call then places the message object back into the event queue
121
paired with an :term:`event handler`::
123
('event', 'message', msg_copy1, custom_event_handler_1)
124
('event', 'message', msg_copy2, custom_evetn_handler_2)
126
5. **Process Custom Events**
128
The stanza and :term:`event handler` are then pulled from the event
129
queue, and the handler is executed, passing the stanza as its only
130
argument. If the handler was registered as threaded, then a new thread
131
will be spawned for it.
134
Events may be raised without needing :term:`stanza objects <stanza object>`.
135
For example, you could use ``self.event('custom', {'a': 'b'})``.
136
You don't even need any arguments: ``self.event('no_parameters')``.
137
However, every event handler MUST accept at least one argument.
139
Finally, after a long trek, our message is handed off to the user's
140
custom handler in order to do awesome stuff::
143
msg['body'] = "Hey! This is awesome!"
147
.. index:: BaseXMPP, XMLStream
149
Raising XMPP Awareness: BaseXMPP
150
--------------------------------
151
While :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream` attempts to shy away
152
from anything too XMPP specific, :class:`~sleekxmpp.basexmpp.BaseXMPP`'s
153
sole purpose is to provide foundational support for sending and receiving
154
XMPP stanzas. This support includes registering the basic message,
155
presence, and iq stanzas, methods for creating and sending stanzas, and
156
default handlers for incoming messages and keeping track of presence
159
The plugin system for adding new XEP support is also maintained by
160
:class:`~sleekxmpp.basexmpp.BaseXMPP`.
162
.. index:: ClientXMPP, BaseXMPP
166
:class:`~sleekxmpp.clientxmpp.ClientXMPP` extends
167
:class:`~sleekxmpp.clientxmpp.BaseXMPP` with additional logic for connecting
168
to an XMPP server by performing DNS lookups. It also adds support for stream
169
features such as STARTTLS and SASL.
171
.. index:: ComponentXMPP, BaseXMPP
175
:class:`~sleekxmpp.componentxmpp.ComponentXMPP` is only a thin layer on top of
176
:class:`~sleekxmpp.basexmpp.BaseXMPP` that implements the component handshake