Basics: Spacebrew + Javascript

Introduction

This tutorial is an introduction to using Spacebrew with browser-based Javascript. We'll use an in-depth break down of the basic button example to give you everything you wanted to know about the Javscript library, but were afraid to ask.

Getting Started: Button Tutorial

  • First things first: download (or clone) the spacebrew.js library. Put it in a folder you love/cherish.
  • Open up the button example: open spacebrew_button/index.html in your favorite browser. It should look something like the image below. Click the button! Notice it does nothing!
  • Now, open up the spacebrew admin. I like to use this nice short bit.ly: bit.ly/sbadmin-cloud
    • You should see your randomized button name (e.g. "button example 6899" above!).
    • Route buttonPress to toggleBackground like so:
  • Return to your button window and press the button. Wow!
  • This may seem kind of boring, but the magic of spacebrew + javascript is that you can host your files. That same button can easily be opened on a smartphone (via the snappy bit.ly/sbbutton) and connected to a PowerTail via an Arduino to create an internet-connected power switch!

Breaking Down the Code: Button Example

Let's dive into the Spacebrew.js code. First, let's look at the way our folder is set up (ignoring my annoying dropbox icons...):

We follow a pretty basic web structure, with a "css" folder of our style files and a "js" folder with our libraries: in this case, jquery and spacebrew.js. This will matter in our index.html, which is where our javascript code for this example lives.

Open up index.html in your favorite text editor (I like Sublime Text). You'll see the button code in a few major parts:

Include the library:

  • On line 11, we include sb-1.4.1.js from that above-noted folder
    (We're also including Jquery here!)
<script type="text/javascript" src="js/sb-1.4.1.js"></script>

Setup the connection

  • We first declare a global object called "sb" we can reference everywhere. This will be our reference to the spacebrew connection.
var sb, 
app_name = "button example";
  • In the function called "setup", we build the connection. You'll notice in line 14 we make sure "setup" gets called when the window loads:

$(window).on("load", setup);
  • Setting our global sb equal to a new Spacebrew.Client() creates the connection object.
    • In the examples, we use the simplest constructor–new Spacebrew.Client()–which connects to the default cloud server (sandbox.spacebrew.cc) at the default port (9000). There are three ways to use the constructor for more complex operation:
      • Spacebrew.Client( server, name, description, options )
        • server = String of host for Spacebrew server, e.g. "sandbox.spacebrew.cc" or "192.0.0.1"
        • name (optional) = name of your app (String)
        • description (optional) = description of your app (String)
        • options (optional) = advanced configuration object, which accepts these optional flags:
          • port: Number - port of Spacebrew server to connect to. Spacebrew is by default always 9000, so be careful!
          • reconnect: Boolean - Automatically try to reconnect if we lose connection to Spacebrew server
          • capSendRate: Boolean - Cap how often Spacebrew sends messages to prevent overloading network
          • sendRate: Number - How often (in milliseconds) we're allowed to send if rate is capped
          • debug: Boolean - Turn on/off debug logging
        • Examples:
          
 
var sb = new Spacebrew.Client("sandbox.spacebrew.cc", "Cool client");
var sb = new Spacebrew.Client("localhost", "Cool", "Very cool", {reconnect: true} );

 

  • Spacebrew.Client( options )
    • options: Object - Configuration object with same options as above plus basics. Any that are omitted revert to defaults.
      • server: String - String of host for Spacebrew server, e.g. "sandbox.spacebrew.cc" or "192.0.0.1".
      • name: String - name of your app 
      • description: String - description of your app
    • Examples
      
 
var sb = new Spacebrew.Client( { server: "sandbox.spacebrew.cc", reconnect: true });
var sb = new Spacebrew.Client( { name: "Great client" } );

 

  • Query strings
    • We also use optional query strings to override/set up our Spacebrew connection. This allows options to be passed directly via the url after the HTML filename.
      • The first query param always starts with "?"; others start with "&"
      • They follow this pattern: name=value
      • Examples
        index.html?name=Cool
        index.html?server=localhost&name=Great&port=9001
    • Supported query parameters are:
      • server
      • name
      • description
      • port
      • debug
    • In our example, we use the second option:
 
sb = new Spacebrew.Client({reconnect:true});

 

ADD PUBLISHERS AND SUBSCRIBERS

  • You can add as many publishers and subscribers as you want by calling "addPublisher" or "addSubscriber" in this format:
    • addPublisher( "NAME", "TYPE", "DEFAULT" )
    • addSubscriber( "NAME", "TYPE" )
    • "TYPE" in both are either "boolean", "string", "range", or a custom type (made up by you!)
  • In our button example, we create a publisher for the button and a subscriber for the background.
 
// configure the publication and subscription feeds
sb.addPublish( "buttonPress", "boolean", "false" );
sb.addSubscribe( "toggleBackground", "boolean" );

EVENTS

We use a simple override pattern to connect to Spacebrew events:

sb.eventName = yourFunction;
(where sb is your Spacebrew object)

You can override as many events as you choose; doing so will call your custom function when an event happens. Your functions must follow the pattern Spacebrew.js provides, otherwise weird stuff may happen. 

Supported events are:

  • onOpen()
  • onClose()
     
  • onRangeMessage( name, value )
    • name: String - Name of incoming route
    • value: Number - Incoming data
  • onBooleanMessage( name, value )
    • name: String - Name of incoming route
    • value: Boolean - Incoming data
  • onStringMessage( name, value )
    • name: String - Name of incoming route
    • value: String - Incoming data
  • onCustomMessage( name, value, type )
    • name: String - Name of incoming route
    • value: String - Incoming data
    • type: String - Name of custom type
  • onBinaryMessage( name, value, type )
    • name: String - Name of incoming route
    • value: Object - {buffer:[received ArrayBuffer], startIndex:[start index for binary data]}
    • type: String - Name of custom type

In the button example, we only receive on a boolean route, so we only override onOpen and onBooleanMessage

// in setup
function setup (){
  // ... other code: see example!
  // line 42 and 43
    sb.onBooleanMessage = onBooleanMessage
    sb.onOpen = onOpen;
  // more code...
}

// below, declaring onBooleanMessage
function onBooleanMessage( name, value ){
        console.log("[onBooleanMessage] boolean message received ", value);
        if (value) {
            document.body.style.background = "rgb(100,255,100)"; 
        } else {
            document.body.style.background = "rgb(220,220,220)";    
        }
}

// declaring onOpen
function onOpen() {
    var message = "Connected as <strong>" + sb.name() + "</strong>. ";
    if (sb.name() === app_name) {
        message += "<br>You can customize this app's name in the query string by adding <strong>name=your_app_name</strong>."
    }
    $("#name").html( message );
}

 

CONNECT

Phew! OK, our Spacebrew connection is setup, we have publishers and subscribers, and are ready to go. Don't forget to call "connect". It's easy! Remember: only call this once! We call it it setup() as well (line 46).

sb.connect();

Send to Spacebrew

In the button example, we use jquery events to connect clicking our button to functions that send to Spacebrew.

Sending is the same for all types:

  • sb.send( name, type, value )
    • name: String - Name of route
    • type: String - Type of route
    • value: String - Value

In our example, we're sending "true" when the button is down, and "false" when the button us up

//button down
sb.send("buttonPress", "boolean", "true");

//button up
sb.send("buttonPress", "boolean", "false");

The important thing to note is that "name" and "type" must match what you declared in "addPublish" and "addSubscribe". Everything else you send will silently, disappointingly, fail.

CONCLUSION

Wow! That's it! Once your connection is set up and active, you can send like crazy and will get messages as they come in from the events you've connected. Now, it's only a few quick steps to set up your own app!

Setting up a new app

We're going build off of the code from above to create a simple mouse-based Spacebrew range sender.

SETUP

  • As you might have guessed, the first step for creating a new web-based spacebrew.js app is to create a similar folder structure as above. You can make it anywhere you like!
    • Using the OS of your choice, create a folder called "spacebrew_mouse_range"
    • Create an index.html file in this folder
    • Create a folder inside that one called "js"
    • Copy the spacebrew.js library from the repository you downloaded into the "js" folder
      • The library is in the spacebrew.js/libraries folder (as of writing it's called "sb-1.4.1.js")

HTML Structure

  • Open the index.html file we just created
  • We're going to add some basic structure, including a code to include our library and a place to write Javascript
<html>
  <head>
    <script type="text/javascript" src="js/sb-1.4.1.js"></script>
    
    <!-- We're going to write Spacebrew code here! -->
    <script>
    </script>
    
    <!-- Minimal CSS to make our empty Body tag fill the page -->
    <style type="text/css">
        html, body {
            width: 100%;
            height: 100%;
        }
    </style>
  </head>
  <body>
  </body>
</html>

SETUP SPACEBREW + CONNECT TO THE MOUSE

Now, we're going to add the lovely code we learned above to connect to Spacebrew, add a publisher and subscriber, and listen to incoming messages.

All of this goes between the <script> tags after you import the Spacebrew library.

function setup(){
    // set up spacebrew connection with defaults
    var sb = new Spacebrew.Client();

    sb.name = "Mouse range";

    // add publishers and subscribers
    sb.addPublish("mouse", "range", "0" );
    sb.addSubscribe("backgroundColor", "range" );

    // listen to events
    // note: different than above, we can just write the
    // function here!
    sb.onRangeMessage = function( name, value ){
        // change the bg color based on the range!
        document.body.style.backgroundColor = "rgb(" + value +"," + value +"," + value + ")"
    }

    // send range based on mouse X

    document.body.onmousemove = function( e ){
        sb.send( "mouse", "range", String(e.clientX));
    }

    // connect
    sb.connect();
}

// connect "setup" to window loading
window.onload = setup;

Not too bad! Once you add this to your HTML, you can open index.html in your browser, connect to the Spacebrew admin, and route yourself together. 

Looking at the code, you'll see a few pieces are a little different than the example. This is mostly an effort to write less code, but there a couple tricky lines in there.

  • Instead of sb.onRangeMessage = ourCustomFunction we're writing the function directly. Totally valid!
  • Everything happens in setup.
  • String(e.clientX): everything you send in Spacebrew must be a string*. So,in Javascript, you'll often call String( SomeData ) when you send to Spacebrew.

* Unless it's binary, but that's a story for a different day!

CONCLUSION II

That's it for a really, really simple app! Check out the examples for some fancier Javascript, some weird stuff (e.g. sending images), and some advanced functionality (the admin API). Happy brewing!