An alternative storage layer for syncing Backbone models/collection with XMPP Pub-Sub nodes
Backbone makes it easy to support alternative storage layers to its default RESTful JSON requests.
This package provides such a layer on top of XMPP Publish-Subscribe through mapping Backbone.Collection
instances to Pub-Sub nodes and their Backbone.Model
instances to items of the node. In addition, it provides support for handling real-time XMPP notifications on these nodes, pushing live updates to the collections/models.
In order for a collection to use the storage, override its sync()
function and provide an instance of PubSubStorage
on the node
attribute of the collection, for instance:
var MyCollection = Backbone.Collection.extend({
sync: Backbone.xmppSync,
model: MyModel,
...
});
var mycollection = new MyCollection();
mycollection.node = new PubSubStorage('mymodels', connection);
where the arguments 'mymodels'
, and connection
are the node id on your XMPP PubSub server, and Strophe's connection object, respectively.
For models, it is not necessary to specify the node (though you can, on the rare occasion where you sync a model without a collection), i.e. the following is sufficient:
var MyModel = Backbone.Model.extend({
sync: Backbone.xmppSync,
...
});
var mymodel = new MyModel();
mycollection.add(mymodel);
That's it! Note that the storage will not take care of creating, configuring the node or managing subscriptions. This should be typically done on the server. However, if you wish to do so client-side, you can by means of utilising the bundled PubSub plugin for Strophe.
If your XMPP server is configured to support PEP-notifications and the user connected is subscribed to the node, you can push real-time updates to your models/collections.
Events are fired by the PubSub Strophe plugin, and you can bind to these in your collections. For example, in the initialize()
of your collection's view, you can do
connection.PubSub.on(
'xmpp:pubsub:item-published:mymodels',
this.itemPublished, this);
in order to bind the xmpp:pubsub:item-published
event of the mycollection
node to the itemPublished
function.
There are four relevant events fired by the PubSub
module:
xmpp:pubsub:item-published
will fire whenever an item is added or updated on a PubSub node. The handler will receive an object with the folliwing attributes:node
(the id of the node),id
(the id of the item) andentry
(the entry containing the XML payload). Bind to this event if you want a central delegation of PubSub events.xmpp:pubsub:item-published:*node_id*
is the same asxmpp:pubsub:item-published
except it fires for items of a specific node only. The parameters it passes to the handler are also the same, omitting of coursenode
.xmpp:pubsub:item-deleted
will fire whenever an item is deleted from a PubSub node. Parameters passed arenode
andid
.xmpp:pubsub:item-deleted:*node_id*
same as above, but will only fire if the item belongs to the node with id*node_id*
.
Base collection/models using the Pub-Sub storage are provided in backbone.xmpp.node.js
, namely PubSubNode
(the collection) and PubSubItem
(the model). These will automatically subscribe to the add/update/delete XMPP events and will trigger the add
, change
, remove
Backbone events, respectively. You can directly extend from them:
var MyModel = PubSubItem.extend({
...
});
var MyCollection = PubSubNode.extend({
model: MyModel,
...
});
var mycollection = new MyCollection([], {id: 'mymodels', connection: connection});
Passing options
to initialize with id
and connection
will initialize the node
as well as setup event handling. You can also specify the node later, or even change it by calling setNode
, i.e. mycollection.setNode('mymodels', connection);
.
If your server supports Result Set Management with PubSub you can do partial incremental fetches, which is useful if you do not want to fetch the entire node. For example,
var last, p = mycollection.fetch({rsm: {max: 50}});
p.done(function (data, rsm) {
last = rsm.last;
});
...
// Later do
mycollection.fetch({rsm: {after: last, max: 50}});
will fetch the first 50 items initially and save the rsm
object literal to last
. Later it will retrieve another 50 items starting from after last
.
Please refer to the annotated source:
Backbone.xmpp will register as an anonymous module if you use requireJS.
Backbone.xmpp is part of todomvc. A demo is available here.
Backbone.xmpp.storage is Copyright (C) 2012 Yiorgis Gozadinos. It is distributed under the MIT license.