Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Alonso Holmes committed Aug 20, 2013
0 parents commit 1ec2bef
Show file tree
Hide file tree
Showing 14 changed files with 651 additions and 0 deletions.
48 changes: 48 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use strict';

module.exports = function(grunt) {

// Project configuration.
grunt.initConfig({
nodeunit: {
files: ['test/**/*_test.js'],
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
gruntfile: {
src: 'Gruntfile.js'
},
lib: {
src: ['lib/**/*.js']
},
test: {
src: ['test/**/*.js']
},
},
watch: {
gruntfile: {
files: '<%= jshint.gruntfile.src %>',
tasks: ['jshint:gruntfile']
},
lib: {
files: '<%= jshint.lib.src %>',
tasks: ['jshint:lib', 'nodeunit']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'nodeunit']
},
},
});

// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');

// Default task.
grunt.registerTask('default', ['jshint', 'nodeunit']);

};
22 changes: 22 additions & 0 deletions LICENSE-MIT
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Copyright (c) 2013 Alonso Holmes at One Mighty Roar

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# valet

Realtime node.js + socket.io server in a box.

## Getting Started
Install the module with: `sudo npm install -g valet`
Run with `valet`

## Documentation
_(Coming soon)_

## Examples
_(Coming soon)_

## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).

## Release History
_(Nothing yet)_

## License
Copyright (c) 2013 One Mighty Roar
Licensed under the MIT license.
13 changes: 13 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"platforms":[
{
"name": "amazon web services",
"trigger":{
"property":"MONIT_SERVICE",
"equals": "node_web_app"
},
"port":80
}
],
"default_port":9200
}
24 changes: 24 additions & 0 deletions examples/example-frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!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('http://localhost:9200/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>
47 changes: 47 additions & 0 deletions lib/node-emitter.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
winston = require "winston"
utils = require './utils'

module.exports = (io, debug = false) ->

winston.error('must pass in socket.io') if not io

# Set logLevel based on debug
logLevel = if debug then 'info' else 'warn'

# Add the console transport to winston
winston.remove winston.transports.Console
winston.add winston.transports.Console,
colorize: true
timstamp: true
level: logLevel

winston.info 'emitter middleware initialized'

(req, res, next) ->

if req.method is "POST"
# Check the input for errors
req.namespace = req.path.substr(1,req.path.length)

winston.info req.namespace

if not req.namespace
res.json 400,
error: 'Must POST to a /namespace'
else if not req.body.event
res.json 400,
error: 'Missing parameter: event'
else if not req.body.data
res.json 400,
error: 'Missing parameter: data'
else
# Parse the data
split = utils.splitter req.namespace
# Emit to the proper clients
utils.emitter split.emit_to, split.socketspace, req.body.event, req.body.data, io
# Call next handler
next()

else
winston.info "Method was #{req.method} -- ignoring"
next()
58 changes: 58 additions & 0 deletions lib/node-emitter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions lib/utils.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
splitter = (namespace) ->

# Trim trailing slashes
while namespace[namespace.length-1] is '/'
namespace = namespace.substr(0,namespace.length - 1)

while namespace[0] is '/'
namespace = namespace.substr(1,namespace.length)

split = namespace.split '/'

# Object to store namespace info, to be emitted along with the POSTed data
socketspace =
raw: namespace
last: null
parsed: {}

# The namespaces to emit to
emit_to = []

# If there are an even number of /items, this is a global POST
if split.length % 2 > 0

# Get the last (finest) namespace component
last = split[split.length - 1]
socketspace.last = last

# winston.info "the namespace is '#{ last }'"
# Emit on this as a root namespace
emit_to.push "/#{last}"

# Emit after every preceding combination of two
built = ''
for arg,idx in split
built += "/#{arg}"
# If on an odd index, this is the end of a pair - so append the last namespace component
if idx % 2 > 0 # odd
if last then emit_to.push("#{built}/#{last}") else emit_to.push(built)
# Add to the params dictionary
socketspace.parsed[split[idx-1]] = split[idx]

{
emit_to: emit_to
socketspace: socketspace
}

emitter = (emit_to, socketspace, event, data, io) ->
# Attach namespace data to the emitted data
data.socket_namespace = socketspace
# Emit to each namespace
for namespace in emit_to
console.log "emitting '#{event}' to members of #{namespace}"
io.of(namespace).emit event,data


module.exports =
splitter: splitter
emitter: emitter
65 changes: 65 additions & 0 deletions lib/utils.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1ec2bef

Please sign in to comment.