XMPP Connection
1 Creating and managing connections
xmpp-connect-client
xmpp-connect-component
xmpp-stop!
2 Sending data
xmpp-send
3 Receiving data
xmpp-receive
xmpp-receive-blocking
4 Asynchronous operation
xmpp-set-handler
xmpp-stop-handler
xmpp-handler
5 Callbacks
xmpp-set-callback
xmpp-set-callback/  once
xmpp-unset-callback
xmpp-callbacks
6 Responding to remote interactions
xmpp-send/  callback
xmpp-send/  await
7 Contracts
stanza/  c
xmpp-handler/  c
xmpp-callback/  c
xmpp-callback/  once/  c
8.12

XMPP Connection🔗ℹ

Navlost <racket at navlost dot eu>

Find the source at https://gitlab.com/navlost.eu/xmpp/libraries/racket/xmpp.

 (require xmpp/transport) package: XMPP

This package implements functions to connect and authenticate with an XMPP server.

Example:

(require xmpp/transport)
(define jid (string->jid "user@example.net"))
(define pass "s3cret!")
(define conn (xmpp-connect-client jid pass))
(xmpp-send conn '(presence ()))

After connecting, the library assigns a unique JID resource automatically:

  "user@example.net/racket-1547"

1 Creating and managing connections🔗ℹ

procedure

(xmpp-connect-client jid passwd [host port])  (xmpp-connection?)

  jid : jid?
  passwd : string?
  host : string? = (jid-domainpart jid)
  port : port-number? = XMPP-C2S-PORT
This method:
  • Creates a xmpp-connection object;

  • connects to the server, either host if provided or else (jid-domainpart jid), either on the default XMPP port (5222) or on port;

  • upgrades the connection to TLS;

  • authenticates the user with the provided jid and passwd;

  • randomises the jid-resourcepart and binds it; and

  • returns the xmpp-connection object, which is used by every other function needing to interact with the server.

procedure

(xmpp-connect-component host    
  port    
  domain    
  secret)  (xmpp-connection?)
  host : string?
  port : port-number?
  domain : string?
  secret : string?
This method creates an XEP-0114 component connection.

procedure

(xmpp-stop! conn)  (any)

  conn : xmpp-connection?
Closes the connection to the server.

2 Sending data🔗ℹ

procedure

(xmpp-send conn stanza)  (any)

  conn : xmpp-connection?
  stanza : xexpr/c
Sends a stanza.

Example:

> (xmpp-send conn '(presence))

3 Receiving data🔗ℹ

There are a number of approaches to receiving data. Incoming stanzas may be processed synchronously (either blocking the execution thread or not) or via callbacks. Callbacks may be one-off or repeating.

procedure

(xmpp-receive conn)  (or/c xexpr/c #f)

  conn : xmpp-connection?
Gets the next available stanza from the connection buffer.

Returns #f if no stanzas are available.

Example:

> (xmpp-receive conn)

#f

procedure

(xmpp-receive-blocking conn)  (xexpr/c)

  conn : xmpp-connection?
Gets the next available stanza from the connection buffer. If the buffer is empty, block until a new stanza is received or the connection is lost.

Example:

> (xmpp-receive-blocking conn)

4 Asynchronous operation🔗ℹ

A common way to interact with XMPP is by registering callbacks. These must conform to the contract xmpp-handler/c and get called whenever a stanza arrives.

procedure

(xmpp-set-handler conn [handler])  (any)

  conn : xmpp-connection?
  handler : xmpp-handler/c = default-handler
Sets a handler that gets called every time a new stanza arrives.

If called with no arguments, the default handler is installed, which is required when using the functions in the Callbacks section.

Otherwise, the argument must be a function taking a stanza (xexpr/c) and a (struct connnection) as arguments. The return value is ignored.

Only one handler may be set per connection. However, it is possible to have arbitrarily many callbacks.

Example:

> (xmpp-set-handler conn (λ (stanza conn)
                           (displayln
                            (~a "Received a new stanza of type "
                                (car stanza)))))

procedure

(xmpp-stop-handler conn)  (any)

  conn : xmpp-connection?
Remove any previously installed handler for conn.

procedure

(xmpp-handler conn)  (or/c xmpp-handler/c #f)

  conn : xmpp-connection?
Return the installed handler for conn, if any. Otherwise, return #f.

5 Callbacks🔗ℹ

For the procedures in this section to operate as intended, the default handler must be installed on the target connection, via (xmpp-set-handler conn).

procedure

(xmpp-set-callback conn callback)  (any)

  conn : xmpp-connection?
  callback : xmpp-callback/c
Install a callback on conn.

procedure

(xmpp-set-callback/once conn callback)  (any)

  conn : xmpp-connection?
  callback : xmpp-callback/once/c
Install a callback that uninstalls itself when it signals to the handler that it’s done by returning #t. These callbacks are the basis for the interactions described in Responding to remote interactions.

Example: Remember to install the default handler.

> (xmpp-set-handler conn)
  
  ; Callback that matches any IQ stanzas of
  ; type "result", prints a message and returns #t.
  (define (iq-result-handler-once stanza conn)
    (match stanza
      ( (list 'iq
              (list-no-order '(type "result") _ ...) _ ...)
        (displayln "An IQ of type result has been seen.")
        #t)
      (_ (void))))
  
  (xmpp-set-callback conn iq-result-handler-once)
  
  ; Two pings are sent, but only the first response to arrive
  ; will cause the callback to run.
  
  (xmpp-send conn
             `(iq ((from ,(jid->string (xmpp-connection-jid conn)))
                   (to ,(jid-domainpart (xmpp-connection-jid conn)))
                   (id ,(xmpp-id)))
                  (ping ((xmlns "urn:xmpp:ping")))))
  
  (xmpp-send conn
             `(iq ((from ,(jid->string (xmpp-connection-jid conn)))
                   (to ,(jid-domainpart (xmpp-connection-jid conn)))
                   (id ,(xmpp-id)))
                  (ping ((xmlns "urn:xmpp:ping")))))
"An IQ of type result has been seen."

procedure

(xmpp-unset-callback conn callback)  (any)

  conn : xmpp-connection?
  callback : xmpp-callback/c
If installed, callback will be removed from this connection. It doesn’t matter if the callback was installed by xmpp-set-callback or xmpp-set-callback/once.

procedure

(xmpp-callbacks conn)  (listof xmpp-callback/c)

  conn : xmpp-connection?
Return the list of callbacks currently installed in this connection.

6 Responding to remote interactions🔗ℹ

procedure

(xmpp-send/callback conn stanza callback)  (any)

  conn : xmpp-connection?
  stanza : xexpr/c
  callback : xmpp-callback/c
Send a stanza and call callback when a response is received.

A response is defined as an incoming stanza of the same type and with the same id.

This is implemented by wrapping callback with the right logic to detect responses and registering the new function via xmpp-callback/once.

Example:

> (define ping
    `(iq ((from ,(jid->string (xmpp-connection-jid conn)))
                    (to ,(jid-domainpart (xmpp-connection-jid conn)))
                    (id ,(xmpp-id)))
                   (ping ((xmlns "urn:xmpp:ping")))))
  
  (xmpp-send/callback conn ping (λ (response conn)
                                  (displayln "PONG!")))
"PONG!"

procedure

(xmpp-send/await conn stanza callback)  (any)

  conn : xmpp-connection?
  stanza : xexpr/c
  callback : xmpp-callback/c
Send a stanza and wait for the result of callback.

This is similar to xmpp-send/callback except that the call will block until callback returns.

7 Contracts🔗ℹ

👉🏽 Contracts in The Racket Guide introduces contracts.

contract

stanza/c : contract?

Defined as:

(or/c xexpr/c #f)

The return value of xmpp-receive (but not xmpp-receive-blocking which always returns an xexpr/c).

contract

xmpp-handler/c : contract?

Defined as:

(-> stanza/c any)

A procedure suitable for xmpp-set-handler.

Defined as:

(-> stanza/c xmpp-connection? any)

A procedure suitable for xmpp-set-callback.

Defined as:

(-> stanza/c xmpp-connection? boolean?)

A procedure suitable for xmpp-set-callback/once.