Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

xmpp4moz internals

brettz9 edited this page Sep 13, 2010 · 6 revisions

(To be updated.)

From lower to upper level:

Transport

  • Files: chrome://xmpp4moz/content/service/transport-tcp.js
  • XPCOM class ID: @hyperstruct.net/xmpp4moz/xmpptransport;1?type=tcp
  • XPCOM interface ID: nsIXMPPTransport
  • Purpose: represents the various low-level transports an XMPP stream might travel on
  • Used by: Service
  • Notes:
    • currently only TCP implemented
    • Service listens to start/stop events by registering an observer
    • Transport → Session communication (i.e. inbound data) is setup by Service, by passing Session to Transport’s asyncRead() method
    • Session → Transport communication (i.e. outbound data) is setup by Service, by listening to Session’s ‘data-out’ event and passing data to Transport’s write() method

Session

  • Files: chrome://xmpp4moz/content/service/client_session.js
  • XPCOM class ID: @hyperstruct.net/xmpp4moz/xmppsession;1
  • XPCOM interface ID: nsIClientSession
  • Purpose: turn raw incoming data and outgoing data into XMPP events
  • Used by: Service
  • Notes:
    • does not directly send outgoing events anywhere, just exposes them to observers for them to dispatch

Service

  • Files: chrome://xmpp4moz/content/service/client_service.js
  • XPCOM class ID: @hyperstruct.net/xmpp4moz/xmppservice;1
  • XPCOM interface ID: nsIClientService
  • Purpose: handles multiple accounts, provides a single entry point for outgoing communication (send()) and incoming (addObserver())
  • Used by: JavaScript API
  • Notes:

JavaScript API

  • Files: chrome://xmpp4moz/content/service/jsapi.js
  • XPCOM class ID: none
  • XPCOM interface ID: none
  • Purpose: provides a JavaScript-idiomatic API (as opposed to XPCOM-ish API) to application developers; tasks include:
    • session establishment and authentication (up(), isUp(), down(), isDown())
    • sending stanzas (send())
    • register handlers for incoming stanzas (channel = createChannel(), channel.on())
    • handle bridge between local XMPP sessions and remote applications (enableContentDocument())
    • provide a few un-official utility routines (nickFor(), presenceSummary())

- Transport receives raw data

  • raw data is passed to listener that was registered via asyncRead()
  • (previously: Service had registered Session as a listener — in Service._openUserSession())
  • Session receives data as argument to onDataAvailable()
  • Session hands it to internal SAX parser
  • parser builds an XMPP stanza
  • parser passes element to Session via Session._element()
  • Session checks whether this is a reply to a previous outgoing stanza
    • if so, invokes the reply handler
  • Session stamps stanza with metadata about account and direction
  • Session dispatches stanza to observers
  • (previously: Service had registered a session observer — Service._openUserSession())
  • Service receives stanza
  • Service applies several business rules, such as:
    • if the stanza indicates that we are leaving a room, synthesize unavailable presences from all room occupants
    • if stanza is a presence or a roster iq, cache it
    • etc.
  • Service dispatches stanza event to its observers
  • (previously: application developer had used XMPP.createChannel() and channel.on() to create listeners)
  • Stanza event surface to application code

XMPP.cache.first()

Note that per bard, “cache_service API is not exposed (yet)”

Note that in such queries, only the jabber:iq:roster, storage:bookmarks, and xmpp4moz (http://hyperstruct.net/xmpp4moz/protocol/internal) namespaces will be recognized with prefixes (‘x4m’, ‘roster’, and ‘bookmarks’, respectively).

Also note that only such queries as are predefined (presence, roster, bookmarks, vCard, and xmpp4moz’s cache-control) have any default caching associated with them. addRule() must be called on the cache service (via ?) to specify more rules to allow caching on other elements, passing an object with:

  • a appliesTo() method that returns a boolean indicating whether to process the rule for a given element and
  • a doApply() method which adds the element in some manner (cache methods insert(), replace(), or remove()) to the cache.

The send() function

1) If a session has already been established for a given account, the stanza will be processed:

a) If the stanza is a an <iq> of type ‘get’ and has a <cache-control xmlns=“http://hyperstruct.net/xmpp4moz/protocol/internal”/> descendant, the stanza will not be sent, but will instead trigger the callback, if present, passing an object with an ‘account’ property set to the user’s JID (and the ‘session’ property’ set to an object with a ‘name’ property set to the user’s JID) and with a ‘stanza’ property set to E4X XML representing <iq type=“result” from=“toTargetOfGetIQ”><query or vCard><meta direction=“in” account=“userJID”>. If no callback is present, the ‘stanza-in’ channel observers will be triggered.*

b) If the stanza is any other kind, the following will take place. If no id attribute is included, a unique-for-the-session (auto-incrementing) id will be created automatically. Any matching observers set on the channel for outgoing stanzas will be triggered**
, and then, if there is still a connection, the stanza will be sent (wrapped with a <meta/> element in the xmpp4moz namespace for tracking purposes). Upon receipt of a reply with the same id from the server, any matching incoming ‘stanza-in’*
observers on the channel will be triggered, and then, the handler, if present, will be called with one argument, an object with an ‘account’ property (set to the user’s JID for this session), a ‘session’ property set to an object which has a ‘name’ property also set to the user’s JID), and a ‘stanza’ property containing the reply stanza in E4X form.

2) If a session is not established for the account and the stanza to be sent is a message with a jabber:x:event <x> child or with children in the chatstates namespace, or if the stanza merely was to announce unavailable presence, no action will be taken (since none is necessary here).

3) Otherwise, if a session has not been established for a given account, up() will be called with a callback to send the current stanza and execute the specified handler upon connection.

  • * Besides channel observing, ‘stanza-in’ observers will trigger caching of certain items like <presence>, roster, bookmark, vCard, and requests, In the case of incoming service discovery requests, a matching <iq type=“result”> will be sent back to the server indicating the identity being a client PC named ‘xmpp4moz’, that service discovery is supported, and any other features added previously if passed to createChannel(). Outgoing stanza observers will be triggered.**
    If there are further responses in turn to this response those incoming observers might be triggered (as in 1b). (Does service discovery work this way?)
  • ** Besides channel observing, ‘stanza-out’ observers will trigger caching of certain items like <presence>, roster, bookmark, vCard, and requests.