lore-hook-websockets-sails

WARNING! This hook is a proof of concept, and has never been used in a production application. It was developed to prove that Lore's architecture accounted for the unique concerns that come with using websockets in a real application, and that the interface developed could work with Sails.

Provides an implementation of lore-websockets designed to work with Sail.js

lore-hook-websockets-sails

Source code for this hook can be found on GitHub at this link.

Purpose

This hook is built on top of the lore-websockets library and implements the interface for Sails.

Example

See the websockets example to see this hook in action.

Example Usage

The Sails hook behaves identical to the SocketIO hook, except for the implementation. The big callout here is that you need to install both the socket.io-client and the sails.io.js package (that takes the socket.io client as an argument).

You also need to set the URL immediately after creating this object, as it will try to call out to the server. Alternatively, you can set io.sails.url.authConnect = false. I'm still playing with this implementation a bit, but am leaning towards that solution (so that it doesn't make ANY server calls until you tell it to).

The other thing to point out is the dispatch implementation. For the most part Sails used a message structure consisting of verb and data fields, but sometimes replaces data with previous when it comes to updated and deleted data. So the parse method has been modified to convert everything into a verb/data structure.

import _ from 'lodash';
import { WebSocketConnection } from 'lore-websockets';
import io from 'socket.io-client';
import SailsIOClient from 'sails.io.js';

const SOCKET_VERBS = {
  CREATED: 'created',
  UPDATED: 'updated',
  DESTROYED: 'destroyed',
  ADDED_TO: 'addedTo'
};

export default WebSocketConnection.extend({

  // serverUrl: 'http://localhost:1337',
  // namespace: '/posts',
  // event: 'post',

  initialize: function(dispatchers, actions) {
    this.io = SailsIOClient(io);
    this.io.sails.url = this.serverUrl;
  },

  connect: function() {
    const namespace = this.namespace;
    // we have to make a GET request to this endpoint before we're connected
    this.io.socket.get(namespace, function() {
      console.log(`Connected to ${namespace}`);
    });
  },

  subscribe: function() {
    this.io.socket.on(this.event, this.dispatch);
  },

  unsubscribe: function() {
    this.io.socket.off(this.event, this.dispatch);
  },

  parse: function(message) {
    if (message.verb === SOCKET_VERBS.CREATED) {
      return {
        verb: message.verb,
        data: message.data
      }
    } else if (message.verb === SOCKET_VERBS.UPDATED) {
      return {
        verb: message.verb,
        data: message.data
      }
    } else if (message.verb === SOCKET_VERBS.DESTROYED) {
      return {
        verb: message.verb,
        data: message.previous
      }
    } else if (message.verb === SOCKET_VERBS.ADDED_TO) {
      return {
        verb: message.verb,
        data: message.data
      }
    } else {
      return {
        verb: 'unknown_verb',
        data: message
      }
    }
  }

});