Valet is a simple server built on node.js and socket.io. You can deploy it locally with one command, or remotely with a few clicks. Clever namespaces allow you to use Valet for multiple projects simultaneously.
Check out this blog post for some background on Valet.
Install the Valet module from npm with:
sudo npm install -g valet
Then run it locally with:
valet
You can verify that Valet is running by visiting http://localhost:9200
in your browser. You should see valet version 0.1.0
.
Log into Amazon Web Services and open up Opsworks.
Create a new stack.
Spin up a new instance, with a size of "micro"
Create a new app (type=node.js) with the following settings:
name: valet
app type: node.js
repository type: git
repository url: https://github.com/onemightyroar/valet.git
Deploy your app. Valet will be pulled from github, and should be available in a few minutes.
Sign up for a free (30day) ndoejitsu account at nodejitsu.com
Install nodejitsu:
sudo npm install -g jitsu
Pull down a local copy of Valet - this is the copy you'll be modifying and deploying.
cd /some/directory/
npm install valet
Edit the subdomain
field in package.json. Your app will be served from your-subdomain.jit.su
Deploy your app:
jitsu deploy
Valet will look for a file called config.json
in your root project directory. If it can't find one, it will use the one located in the valet root. If you want to name your amazon app zomething other than valet, you should copy the included config.json file and tweak it as needed.
Namespaces split clients into groups, to allow many projects to use a single Valet instance simultaneously.
Clients (frontends, devices, or even other servers) determine what namespaces they want to join by connecting to a specific URL. Multiple namespaces can be joined by calling connect
multiple times (only one websocket connection will actually be used).
For example, to join the /temperature
and /humidity
namespaces, your client would have code that looks something like:
temperature = io.connect('http://localhost:9200/temperature')
humidity = io.connect('http://localhost:9200/humidity')
Valet extends socket.io's namespaces in a useful way: if you use more complex namespaces, your events and data will "bubble up". For example, data you send to a namespace like /buildings/123/rooms/456/temperature
will be emitted on the following three namespaces:
/buildings/123/rooms/456/temperature
/buildings/123/temperature
/temperature
This means that you can listen to /buildings/123/rooms/456/temperature
to get events from temperature sensors in room 456, /buildings/123/temperature
to get events from all of the temperature sensors in building 123, or /temperature
to get events from all of the temperature sensors, everywhere.
You can pass data to Valet by either sending a POST request to your Valet server, or by emitting a socket event called "post". For example, to send data from your terminal using CURL:
curl -X POST -H "Content-Type: application/json" -d '{"event":"reading","data":{"temp":83.3826}}' http://localhost:9200/buildings/123/rooms/456/temperature
Note - if your client does not support sending an application/json
, you can send the json as a string in the POST body called value
To send the same data using a socket is a two step process - first, you must connect to your Valet server on the root namespace. Then, emit an event called post
containing the event
, namespace
, and data
you would like to emit. For example:
temperature = io.connect('http://localhost:9200');
temperature.emit('post',{
event:"reading",
namespace:"/buildings/123/rooms/456/temperature",
data:{temp:83.3826}
});
In either case, an event called reading
with data {temp:83.3826}
will be emitted on the three namespaces described in the "Namespaces" section above.
Anything that can run socket.io can be a Valet client. Simply require socket.io on your client, connect on whatever namespaces you like, and listen for events.
Here is an example client that listens for temperature readings. To demonstrate the namespace "event bubbling" behavior described above, this example listens for events on the /buildings/123/temperature
namespace, even though they will be sent to the server on the /buildings/123/rooms/456/temperature
namespace.
```HTML
<!DOCTYPE html>
<head>
<!-- Valet serves up socket.io.js on a special endpoint -->
<script src="http://localhost:9200/socket.io/socket.io.js"></script>
<script type="text/javascript">
// Connect on the "buildingTemp" namespace
var buildingTemp = io.connect('/buildings/123/temperature');
// "Connect" events are fired when the connection happens successfully
buildingTemp.on('connect',function(){
console.log('connected to the "buildingTemp" namespace!');
});
// Listen for the "reading" event we will be POSTing
buildingTemp.on('reading',function(data){
console.log('Got data on the "buildingTemp" namespace!');
console.log(data);
});
</script>
</head>
<body></body>
```
- Valet stopped immediately after starting, with no error message. What's up?
- Usually this is due to a port conflict - make sure you don't have any other instances of Valet running, or anything else on port 9200. You can also change the default port in the config.json file in the Valet root folder.
Copyright (c) 2013 One Mighty Roar Licensed under the MIT license.