Best Practice: Glue to Strophe.js


#1

Hi,

I am working on a chat client based on Ember.js and Strophe.js (XMPP). So far I made only very little progress because it was really hard to get a grasp of Ember.js at first. However, I have to say that my code would never have been so structured and that I feel speeding up.

So right now I have my own model classes extended from Ember.Object which receive data (stanzas in this case) via a small pubsub library from a small wrapper around Strophe.js. The next step is to send data via Strophe.js but I am not sure what the best practice would be. I see two options:

  1. Have the wrapper subscribe and the models publish data. Maybe even replace the pubsub library with Ember.Instrumentation. In this way other models could even listen to actions.
  2. Have the models call methods from the wrapper. However, I would have to expose the wrapper to all models somehow and other models wouldn’t be able to listen.

What do you say is the best way to have the models talk to Strophe.js? Also, should the controllers be able to talk to Strophe.js or should it be completely transparent through the models?

Thanks a lot, Karsten


#2

At my last job, I worked on a large SproutCore app that had data backing from an XMPP server. I would recommend that you think of the domain objects that are being sent to / from your XMPP server. If you map these well to Ember Objects / Models, then your UI will be fairly effortless. Here’s a gist of a working SproutCore data source: https://gist.github.com/tim-evans/1510948 (Note that this doesn’t map very cleanly to Ember, but it’s pretty complete in terms of basic cases).

And I would recommend against using raw Strophe, as there’s a lot of edge cases and XMPP XEP conformity that you might bump your head against. I wrote a wrapper library on top of Strophe to manage some of the popular RFC / XEP defined behaviours: https://github.com/onsip/XCJS

It’s an uphill battle, but it’s definitely possible to make a performant XMPP client using a pure JS frontend. Good luck!


#3

Thanks for your answer. XCJS looks pretty good.

What do you mean with “domain objects”?

I am not sure yet how to handle the store and sending a message. So far all models have their own store which is usually a simple array or and object. My messages are bundled in a model called conversation. So following the ember-data API I would call createRecord on my conversation model and it would create a message model, save it to its store and call the send method. Is that the correct approach?

Thanks a lot, Karsten


#4

That sounds reasonable enough. By domain objects, I mean how your data is being modeled in the scope of your problem domain (XMPP), And yea, that seems mostly right. The model we used on the app was:

Contact has_many conversations
        has_one rosterItem // XMPP Roster Item (bareJID)
        has_many resources // XMPP resources (fullJID)
        has_one vcard

Conversation has_one to
             has_one from // This can be >1 if you're on a MUC
             has_one chatState // For chat state notifications,
                               // only keep the most recent one
             has_many messages

And so on… I think you get the picture.


#5

Ah okay. That’s about how I wanted to do it.