├── .editorconfig ├── .gitignore ├── Procfile ├── README.md ├── app.js ├── controllers └── badges.js ├── lib ├── redis.js └── socket.js ├── models └── badges.js └── package.json /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*.js] 3 | 4 | indent_style = space 5 | indent_size = 2 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dump.rdb 3 | export.sh 4 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node app.js 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Node.js Watch Us Build - Pub/Sub Server 2 | 3 | *We changed the name of this series to "Watch Us Build," so you may see an occasional reference to its former name ("Soup to Bits") in this repository.* 4 | 5 | This repo is the source code for the Code School Node.js Watch Us Build Pub/Sub Server. 6 | 7 | Be sure to clone the [webserver](https://github.com/codeschool/WatchUsBuild-ImageStreamingAppWithNodeWebServer) and run it also. 8 | 9 | ### Getting started 10 | 11 | To run this server, you'll need a few things: 12 | 13 | 1. [Node.js](http://nodejs.org) installed 14 | 2. [Redis](http://redis.io) installed and running on `localhost` 15 | 3. [data producer](https://gist.github.com/TJkrusinski/10735569) running 16 | 17 | Then: 18 | 19 | ``` 20 | $ https://github.com/codeschool/WatchUsBuild-ImageStreamingAppWithNodePubSubServer.git 21 | $ cd WatchUsBuild-ImageStreamingAppWithNodePubSubServer 22 | $ npm install 23 | $ node app.js 24 | ``` 25 | 26 | ## License 27 | 28 | (The MIT License) 29 | 30 | Copyright (c) 2014 TJ Krusinski <tjkrsu@gmail.com> 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining 33 | a copy of this software and associated documentation files (the 34 | 'Software'), to deal in the Software without restriction, including 35 | without limitation the rights to use, copy, modify, merge, publish, 36 | distribute, sublicense, and/or sell copies of the Software, and to 37 | permit persons to whom the Software is furnished to do so, subject to 38 | the following conditions: 39 | 40 | The above copyright notice and this permission notice shall be 41 | included in all copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 44 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 45 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 46 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 47 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 48 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 49 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'); 4 | var badges = require('./controllers/badges'); 5 | 6 | var app = express(); 7 | var port = process.env.PORT || 8000; 8 | 9 | /** 10 | * Have our server listen on port 8000 11 | */ 12 | app.listen(port, function(){ 13 | console.log('Server running on port %d', port); 14 | }); 15 | 16 | /** 17 | * Parse json data from incoming reuqests 18 | */ 19 | app.use(express.json()); 20 | 21 | /** 22 | * Accept POST requests and then publish the body of the request 23 | */ 24 | app.post('/', badges.save, badges.trim, badges.send); 25 | 26 | /** 27 | * Get the most recent 10 badges 28 | */ 29 | app.get('/badges', badges.get); 30 | -------------------------------------------------------------------------------- /controllers/badges.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var badges = require('../models/badges'); 4 | var _ = require('underscore'); 5 | 6 | /** 7 | * Save our badges 8 | */ 9 | exports.save = function(req, res, next) { 10 | var badgeList = _.clone(req.body); 11 | badges.save(badgeList, function(err, data){ 12 | if (err) return res.send(503, err); 13 | next(); 14 | }); 15 | }; 16 | 17 | /** 18 | * Trim the badges 19 | */ 20 | exports.trim = function(req, res, next) { 21 | badges.trim(); 22 | next(); 23 | }; 24 | 25 | /** 26 | * Send our badges 27 | */ 28 | exports.send = function(req, res, next) { 29 | var badgeList = _.clone(req.body); 30 | badges.send(badgeList); 31 | res.send(200, 'success'); 32 | }; 33 | 34 | /** 35 | * Get our badges 36 | */ 37 | exports.get = function(req, res, next) { 38 | badges.get(function(err, data){ 39 | res.json(err ? 503 : 200, { 40 | error: err ? true : null, 41 | errorMessage: err ? err : null, 42 | data: data 43 | }); 44 | }); 45 | }; 46 | -------------------------------------------------------------------------------- /lib/redis.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var port = process.env.REDIS_PORT || 6379; 4 | var host = process.env.REDIS_HOST || 'localhost'; 5 | var auth = process.env.REDIS_AUTH || null; 6 | 7 | var redis = require('redis'); 8 | var client = redis.createClient(port, host); 9 | 10 | if (auth) client.auth(auth); 11 | 12 | client.on('error', function(err){ 13 | throw err; 14 | }); 15 | 16 | module.exports = client; 17 | -------------------------------------------------------------------------------- /lib/socket.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var axon = require('axon'); 4 | var socket = axon.socket('pub'); 5 | 6 | /** 7 | * Bind the pub socket to localhost:8001 8 | */ 9 | socket.bind(8001); 10 | 11 | /** 12 | * On error 13 | */ 14 | socket.on('error', function(err){ 15 | throw err; 16 | }); 17 | 18 | /** 19 | * publish the badge to the pub/sub system 20 | */ 21 | exports.send = function(data){ 22 | socket.send(data); 23 | }; 24 | -------------------------------------------------------------------------------- /models/badges.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var redis = require('../lib/redis'); 4 | var socket = require('../lib/socket'); 5 | 6 | /** 7 | * Save a message in the db 8 | */ 9 | exports.save = function(badges, callback) { 10 | if (!badges.length) return callback(null, null); 11 | var badge = badges.pop(); 12 | 13 | redis.lpush('badges', JSON.stringify(badge), function(err, data){ 14 | if (err) return callback(err, null); 15 | exports.save(badges, callback); 16 | }); 17 | }; 18 | 19 | /** 20 | * Trim down the redis list 21 | */ 22 | exports.trim = function() { 23 | redis.ltrim('badges', 0, 9, function(err){ 24 | if (err) throw err; 25 | }); 26 | }; 27 | 28 | /** 29 | * Send badges to the socket 30 | */ 31 | exports.send = function(badges) { 32 | badges.forEach(socket.send); 33 | }; 34 | 35 | /** 36 | * Get badges 37 | */ 38 | exports.get = function(callback) { 39 | redis.lrange('badges', 0, -1, function(err, data){ 40 | if (err) return callback(err, null); 41 | callback(null, data.map(JSON.parse)); 42 | }); 43 | }; 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "soup-to-bits-pub-sub", 3 | "version": "0.0.0", 4 | "description": "soup to bits pub sub", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "mocha tests" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/codeschool/nodejs-soup-to-bits.git" 12 | }, 13 | "keywords": [ 14 | "soup", 15 | "to", 16 | "bits", 17 | "pub", 18 | "sub" 19 | ], 20 | "author": "TJ Krusinski ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/codeschool/nodejs-soup-to-bits/issues" 24 | }, 25 | "homepage": "https://github.com/codeschool/nodejs-soup-to-bits", 26 | "dependencies": { 27 | "axon": "^2.0.0", 28 | "express": "^3.5.1", 29 | "redis": "^0.10.1", 30 | "underscore": "^1.6.0" 31 | }, 32 | "engines": { 33 | "node": "0.10.x" 34 | } 35 | } 36 | --------------------------------------------------------------------------------