Components

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())

Lifecycle of incoming data

  • 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