XMPPFramework version 2.0

129 views
Skip to first unread message

Robbie Hanson

unread,
Mar 26, 2010, 5:29:04 PM3/26/10
to xmppfr...@googlegroups.com
Version 2.0 of the XMPPFramework is now available!

I have done a HUGE amount of refactoring to the XMPPFramework. I believe the changes will be great benefit to anyone using the framework, especially those developing extensions (either standard XEP's or custom extensions). However due to several public facing API changes, this framework will require a bit of refactoring to those currently using the framework in their application.

One of the primary changes you are likely to notice is this:
I have deleted XMPPClient from the XMPPFramework.

Now, I know you must be thinking, "Mr. Hanson you're insane!" But I assure you everything will be OK. In the end, you'll have a better and more extensible xmpp framework. And it will ship with more included extensions.

So what's the thought process?

As the xmpp framework has matured, it has become clear that the XMPPClient was half-baked and has fractured 3rd party development. The truth of the matter is that XMPPClient was originally designed to be a simple example of how one might use the underlying XMPPStream.  But then we added some basic roster management and other little things like automatic reconnect. People saw this and assumed that XMPPClient was what they had to use, but ended up finding it rather brittle.

Take a look at what XMPPClient does:

1. Provides basic roster functionality (poorly)
2. Inflexible security options
3. General XMPPStream wrapper

To go into more detail:

1. The XMPPClient provided a roster by storing the information in memory, accessed via a hashtable. Furthermore it was a closed solution which didn't allow developers to add custom information or properties to a user or resource.  Almost anybody who used the xmpp framework ended up finding this solution to be brittle. And what about core data? If you're working with the framework on the iPhone or any environment where there are a lot of users, core data is a much better solution. Plus harnessing core data allows one to easily implment things like roster animation when users sign online/offline.  There really needs to be a general purpose XMPPRoster class that abstracts the storage mechanism, which would allow you to choose the proper storage, or even write your own.

2. The security options (such as allowSelfSignedCertificates or allowSSLHostNameMismatch) don't go far enough.  On multiple occasions I've been forced to tell developers to manually edit the XMPPStream class in order to allow them to connect to their development server. What we really need is a delegate callback that allows the developers to supply all the various available security options to the stream. This way they have the full potential of the underlying security options via Apple's CFStream.

3. Besides the roster stuff, the entire XMPPClient is just a dumb wrapper around XMPPStream. As in, you invoke a method on XMPPClient, and it literally just turns around and invokes the same method on its underlying XMPPStream. There's really not a lot of point to this.

The other major problem is that extension developers didn't know which class to tie into. Do they tie into XMPPClient or XMPPStream? I've had many developers tell me that they didn't use XMPPClient, and that all their custom extensions tied directly into an altered XMPPStream. Due to this, I was unable to add their extensions to the repository.

So what I've decided to do is merge the good parts of XMPPClient into XMPPStream.

For example, XMPPClient had a way to directly set the JID of the user. This was simple, and useful because XMPPStream wanted the various parts of the JID separately. So now the XMPPStream has a myJID property that can be set.

And so I've done a huge refactoring of the XMPP Framework

*There is a new XMPPRoster class*

It provides the basic methods for a roster, and has a storage abstraction (XMPPRosterStorage protocol). I've provided 2 sample implementations:

- XMPPRosterMemoryStorage which uses the old hashtable technique
- XMPPRosterCoreDataStorage which provides a sample core data storage implementation

You are free to customize either of these, or implement your own from scratch. The idea is that the XMPPRoster class handles the basics like requesting the roster and queueing presence elements. It also has basic methods for adding buddies, and accepting/rejecting buddy requests. But it relies on an XMPPRosterStorage implementation for the actual storage, and it provides a really simple straight-forward API for storage classes to implement.  Implement this API and you have complete control over how/where you store your roster and what kind of data you store concerning it.

*There is a new XMPPReconnect class*

Previously if you wanted automatic reconnect, you had to use XMPPClient. All of the implementation and more has been moved into its own class. If you want to use it, simply plug it into the XMPPStream. Furthermore, it has new methods for general network monitoring. For example, say the user tries to connect to the xmpp server for the first time but isn't connected to the Internet. Since they've never connected, automatic reconnect doesn't apply. The XMPPReconnect class allows you to manually start monitoring the network for changes. This way you could listen for an Internet connection, and automatically connect when one appears.

*New security delegate methods in XMPPStream*

Options like allowSelfSignedCertificates and allowSSLHostNameMismatch do not cut it. This becomes apparent as soon as one tried to connect to a google server. In fact there has been an outstanding ticket about this for quite some time.

Here's the problem:
For a normal google talk session you connect to "talk.google.com" with a JID like "us...@gmail.com". According to the RFC, the xmpp server's certificate is supposed to have the name "talk.google.com". But google's certificate name is "gmail.com". In addition to this, if you use google apps for your domain then you connect to their server at "talk.google.com" with a JID like "us...@yourDomain.com". In this case, the certificate's name is "talk.google.com".

Now the allowSSLHostNameMismatch option would kinda help, but wasn't exactly the perfect option. What was really needed was the ability to directly specify what name is expected to be on the certificate.

The new xmppStream:willSecureWithSettings: allows you to specify this directly. In addition, you can specify a whole bunch of other security settings that were previously not exposed.

*New delegate hooks in XMPPStream for extension development*

A solid example will really help highlight how much this will help.

XEP-0115 specifies a way for clients to broadcast their capabilities and discover the capabilities of other users. (For example, support for audio, video, file transfer, message receipts, etc.) This ties into the presence element. So when the client sends its presence element, it includes this information. And when it receives a presence element, it processes the capabilities information in the element.

The problem was, every part of the application that wanted to send a presence element would have to be sure to include the capabilities information. This makes it very difficult to simply plug in xmpp extensions to an existing application.

But not anymore. There are now hooks that extension classes can use:

- (void)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq;
- (void)xmppStream:(XMPPStream *)sender willSendMessage:(XMPPMessage *)message;
- (void)xmppStream:(XMPPStream *)sender willSendPresence:(XMPPPresence *)presence;

Using these hooks, a XEP-0115 extension would just listen for outgoing presence elements, and could automatically add the capabilities information as needed!

*New XMPPCapabilities extension class*

Yup, an implementation of XEP-0115. It also contains a storage abstraction (XMPPCapabilitiesStorage protocol) so you can choose to cache the capabilities information in any way you want.



I understand that these are really big changes, and will require a bit of refactoring on your part within your application. In order to help understand the impact, and understand the changes needed, I've updated all the sample applications included in the repository.

The desktop project (XMPPStream) demonstrates using XMPPRosterMemoryStorage (just like the old XMPPClient), and also makes use of the XMPPReconnect functionality (again just like the old XMPPClient). It also demonstrates the new security delegate methods to specify the expected X509 certificate domain if connecting to Google Talk.

The iphone project (iPhoneXMPP) demonstrated using XMPPRosterCoreDataStorage to store the roster in core data!

Let me know your thoughts, and if you have any questions.

-Robbie Hanson

StuFF mc

unread,
Mar 26, 2010, 5:34:58 PM3/26/10
to xmppfr...@googlegroups.com
Bravo Robbie! Haven't read all yet but congrats!

However, since I guess you don't have anything MUC-related (and since
I'm already pretty far in my project - and I've used the service
branch), I'm not gonna switch for this project. But I'm sure I'll do
other cool stuffs with XMPP in the future.

In fact, since I discovered XMPP I'm looking for a server side
framework (something like Rails or any of the PHP "rails-alike") that
would be based on XMPP instead of HTTP :-)

Cheers.

> --
> You received this message because you are subscribed to the Google Groups
> "XMPPFramework" group.
> To post to this group, send email to xmppfr...@googlegroups.com.
> To unsubscribe from this group, send email to
> xmppframewor...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/xmppframework?hl=en.
>

Dan Brickley

unread,
Mar 26, 2010, 5:37:35 PM3/26/10
to xmppfr...@googlegroups.com
On Fri, Mar 26, 2010 at 10:29 PM, Robbie Hanson <robbie...@deusty.com> wrote:
> Version 2.0 of the XMPPFramework is now available!

Really great to see all this work going into the library. While it
does look like a pile of work adjusting, I'm sure it's worth it. XMPP
is a moving landscape, so we are lucky to be working with an actively
maintained project.

A question - I saw the comment about reflecting the roster into local
core data, and wonder if you can outline how users should best
integrate the Serverless XMPP (XEP-0174) implemention, ie.
http://code.google.com/p/xmppframework/source/browse/#svn/trunk/iPhone/ServerlessDemo
... particularly if we want the same entities to be available over
slower server-based links, or talking directly over the local LAN.
Since it seems to be time for reorganizing my code, I'd like to move
in the right direction here. My hope is to maintain both serverless
and server-based activities simultaneously, and to have a reasonably
sane approach to maintaining local and server-based rosters.

Anyway, never mind all that, you deserve a break! Nice work on v2.0, I
look forward to getting it running :)

cheers,

Dan

Robbie Hanson

unread,
Mar 27, 2010, 7:27:32 AM3/27/10
to xmppfr...@googlegroups.com
Luke and I have been taliking about porting the muc stuff into the
trunk. It should be a lot easier now with v2.0.

-Robbie Hanson

Robbie Hanson

unread,
Mar 27, 2010, 7:39:42 AM3/27/10
to xmppfr...@googlegroups.com
Apple does this (in iChat) by having separate rosters windows.
(bonjour being the serverless one.)

Now, it is possible to integrate them into a single roster/window.
Obviously you could display all resources, and use an icon to
distingush serverless resources. What we did in Mojo was integrate
them, but automatically remove standard xmpp resources that were
available via P2P (on the local network). We did this by having all
clients broadcast a uuid. This uuid was in the xmpp presence element,
and in the bonjour txt record.

-Robbie Hanson

StuFF mc

unread,
Mar 27, 2010, 7:55:27 AM3/27/10
to xmppfr...@googlegroups.com
GREAT news!


Sent from my iPhone

Deminem

unread,
Mar 29, 2010, 11:41:34 AM3/29/10
to XMPPFramework
That's really a great news! coz I've just about to port this XMPP
framework in one of the project but now having the updated version in
the beginning will be bonus.

Thanks,
Adnan

On Mar 27, 4:55 pm, StuFF mc <m...@stuffmc.com> wrote:
> GREAT news!
>
> Sent from my iPhone
>

> Am 27.03.2010 um 12:27 schrieb Robbie Hanson <robbiehan...@deusty.com>:
>
> > Luke and I have been taliking about porting the muc stuff into the  
> > trunk. It should be a lot easier now with v2.0.
>
> > -Robbie Hanson
>
> > On Mar 26, 2010, at 5:34 PM, StuFF mc <m...@stuffmc.com> wrote:
>
> >> Bravo Robbie! Haven't read all yet but congrats!
>
> >> However, since I guess you don't have anything MUC-related (and since
> >> I'm already pretty far in my project - and I've used the service
> >> branch), I'm not gonna switch for this project. But I'm sure I'll do
> >> other cool stuffs with XMPP in the future.
>
> >> In fact, since I discovered XMPP I'm looking for a server side
> >> framework (something like Rails or any of the PHP "rails-alike") that
> >> would be based on XMPP instead of HTTP :-)
>
> >> Cheers.
>

> >> On Fri, Mar 26, 2010 at 10:29 PM, Robbie Hanson <robbiehan...@deusty.com

> >>> like "u...@gmail.com". According to the RFC, the xmpp server's


> >>> certificate is supposed to have the name "talk.google.com". But  
> >>> google's
> >>> certificate name is "gmail.com". In addition to this, if you use  
> >>> google apps
> >>> for your domain then you connect to their server at  
> >>> "talk.google.com" with a

> >>> JID like "u...@yourDomain.com". In this case, the certificate's  

> ...
>
> read more »

Reply all
Reply to author
Forward
0 new messages