Edit Page

Resourceful PubSub

Overview

For apps that rely heavily on realtime client-server communication--for example, peer-to-peer chat and social networking apps--sending and listening for socket events can quickly become overwhelming. Sails helps smooth away some of this complexity by introducing the concept of resourceful pubsub (Publish / Subscribe). Every model (AKA resource) in your app is automatically equipped with class methods which provide a conventional, data-centric interface for both broadcasting notifications and subscribing sockets to notifications about individual database records being created, updated, or destroyed.

If your app is currently using the Blueprint API, you are already using resourceful pubsub methods! They are embedded in the default blueprint actions bundled with Sails, and called automatically when those actions run; causing requesting sockets to be subscribed when data is fetched and messages to be broadcasted to already-subscribed sockets when data is changed.

But even when writing custom code, you can call the methods described in this section manually in lieu of using sails.sockets.* methods directly. Think of resourceful pubsub methods as a way of standardizing the interface for socket communication across your application: things like the names for rooms, the schema for data transmitted as socket messages, and the names of socket events. These methods are designed exclusively for scenarios where one or more user interfaces are listening to socket events as a way of keeping in sync with the backend. If that does not fit your use case or if you are having trouble deciding, don't worry; just call sails.sockets.broadcast(), sails.sockets.join(), or sails.sockets.leave() directly instead. It is perfectly acceptable to use either approach, or even both approaches in the same app.

Listening for events on the client

While you are free to use any Javascript library to listen for socket events on the client, Sails provides its own socket client called sails.io.js as a convenient way to communicate with the Sails server from any web browser or Node.js process that supports Socket.io. Using the Sails socket client makes listening for resourceful pubsub events as easy as:

io.socket.on('<model identity>', function (event) {
});

The model identity is typically the lowercased version of the model name, unless it has been manually configured in the model file.

Example

Let’s say you have a model named User in your app, with a single “name” attribute. First, we’ll add a listener for “user” events:

io.socket.on('user', function(event){console.log(event);})

This will log any notifications about User models to the console. However, we won’t receive any such messages until we subscribe to the existing User records (aka model instances). If your app currently has the blueprint API enabled, you can use the sails.io.js client to watch the User model for new records, as well as subscribing to the returned set of records by making a socket GET request from the client to /user:

io.socket.get('/user', function(resData, jwres) {console.log(resData);})

This requests the current list of users from the Sails server, and subscribes the client to events about each user. Additionally, if the autoWatch setting is on (the default), the client will also be notified whenever a new User is created, and will automatically be subscribed to the new user. The callback in this example simply logs the user list to the console. See the socket.get reference for more info about this method.

It’s important to note that in order for the subscription to take place, the /user request must be made via a websocket call, not a regular HTTP request. That is, using an AJAX request (e.g. jQuery.get("/user")) will not result in the client being subscribed to resourceful pubsub messages about User. However, once the subscription is made, any changes to models--whether they be the result of a socket call, an AJAX request, even a cURL request from the command line--will cause the client to receive a notification. Continuing with the above example, if you were to open up a new browser window and go to the following URL:

/user/create?name=joe

You would see something like the following in the console of the first window:

{
    verb: 'created',
  id: 1,
  data: {
    id: 1,
    name: 'joe',
    createdAt: '2014-08-01T05:50:19.855Z'
    updatedAt: '2014-08-01T05:50:19.855Z'
  }
}

The verb indicates the kind of action that occurred. The id refers to the record that the alleged action occurred on, and data contains new/modified information about the User that was acted upon. Each event type sends back slightly different information; see the individual resourceful pubsub method reference documents for more info.

Is something missing?

If you notice something we've missed or could be improved on, please follow this link and submit a pull request to the sails-docs repo. Once we merge it, the changes will be reflected on the website the next time it is deployed.

Sails logo
  • Home
  • Get started
  • Support
  • Documentation
  • Documentation

For a better experience on sailsjs.com, update your browser.

Documentation

Reference Concepts App structure | Upgrading Contribution guide | Tutorials More

Reference

  • Application
    • Events
    • Lifecycle
    • sails.getRouteFor()
    • sails.getUrlFor()
    • sails.lift()
    • sails.load()
    • sails.log()
    • sails.lower()
    • sails.request()
    • sails.getBaseUrl()
  • Blueprint API
    • add to
    • create
    • destroy
    • find one
    • find where
    • populate where
    • remove from
    • update
  • Command Line Interface
    • sails console
    • sails debug
    • sails generate
    • sails lift
    • sails new
    • sails version
  • Configuration
    • sails.config.*
    • sails.config.blueprints
    • sails.config.bootstrap()
    • sails.config.connections
    • sails.config.cors
    • sails.config.csrf
    • sails.config.globals
    • sails.config.http
    • sails.config.i18n
    • sails.config.log
    • sails.config.models
    • sails.config.policies
    • sails.config.routes
    • sails.config.session
    • sails.config.sockets
    • sails.config.views
  • Request (`req`)
    • req.accepted
    • req.acceptedCharsets
    • req.acceptedLanguages
    • req.body
    • req.cookies
    • req.fresh
    • req.headers
    • req.host
    • req.ip
    • req.ips
    • req.isSocket
    • req.method
    • req.options
      • req.options.values
      • req.options.where
    • req.originalUrl
    • req.params
    • req.path
    • req.protocol
    • req.query
    • req.secure
    • req.signedCookies
    • req.socket
    • req.subdomains
    • req.url
    • req.wantsJSON
    • req.xhr
    • req.accepts()
    • req.acceptsCharset()
    • req.acceptsLanguage()
    • req.allParams()
    • req.file()
    • req.get()
    • req.is()
    • req.param()
  • Response (`res`)
    • res.attachment()
    • res.badRequest()
    • res.clearCookie()
    • res.cookie()
    • res.created()
    • res.forbidden()
    • res.get()
    • res.json()
    • res.jsonp()
    • res.location()
    • res.negotiate()
    • res.notFound()
    • res.ok()
    • res.redirect()
    • res.send()
    • res.serverError()
    • res.set()
    • res.status()
    • res.type()
    • res.view()
  • Waterline (ORM)
    • Models
      • .count()
      • .create()
      • .destroy()
      • .find()
      • .findOne()
      • .findOrCreate()
      • .native()
      • .query()
      • .stream()
      • .update()
    • Populated Values
      • .add()
      • .remove()
    • Queries
      • .exec()
      • .limit()
      • .populate()
      • .skip()
      • .sort()
      • .where()
    • Records
      • .save()
      • .toJSON()
      • .toObject()
  • WebSockets
    • Resourceful PubSub
      • .message()
      • .publishAdd()
      • .publishCreate()
      • .publishDestroy()
      • .publishRemove()
      • .publishUpdate()
      • .subscribe()
      • .unsubscribe()
      • .unwatch()
      • .watch()
      • .subscribers()
    • sails.sockets
      • .addRoomMembersToRooms()
      • .blast()
      • .broadcast()
      • .getId()
      • .join()
      • .leave()
      • .leaveAll()
      • .removeRoomMembersFromRooms()
      • sails.sockets.emit()
      • sails.sockets.id()
      • sails.sockets.rooms()
      • sails.sockets.socketRooms()
      • sails.sockets.subscribers()
    • Socket Client
      • io.sails
      • io.socket
      • SailsSocket
        • Methods
        • Properties
      • io.socket.delete()
      • io.socket.get()
      • io.socket.off()
      • io.socket.on()
      • io.socket.post()
      • io.socket.put()
      • io.socket.request()

Built with Love

The Sails framework is maintained by a web & mobile studio in Austin, TX, with the help of our contributors. We created Sails in 2012 to assist us on Node.js projects. Naturally we open-sourced it. We hope it makes your life a little bit easier!

Sails:
  • What is Sails?
  • Treeline IDE
  • Contribute
  • Logos/artwork
About:
  • The Sails Company
  • Security
  • News
  • Legal
Help:
  • Get started
  • Documentation
  • Docs
  • Enterprise
  • Hire us

© 2012-2018 The Sails Company. 
The Sails framework is free and open-source under the MIT License.