From 896074c91d2e0a51a313e8fe2064202120e71e8d Mon Sep 17 00:00:00 2001 From: "dan.entous" Date: Fri, 5 Apr 2013 17:20:52 +0200 Subject: [PATCH 1/5] adding in initial draft of the chattr app --- README.md | 19 ++++++++- app.js | 77 +++++++++++++++++++++++++++++++++++++ index.html | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 31 +++++++++++++++ 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 app.js create mode 100644 index.html create mode 100644 package.json diff --git a/README.md b/README.md index cbba4e2..ce944a6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,20 @@ # Real Time Web With Node.js -This is the code for the [Real Time Web with Node.js](http://www.codeschool.com/courses/real-time-web-with-nodejs) demo app. +This is the code for the [Real Time Web with Node.js](http://www.codeschool.com/courses/real-time-web-with-nodejs) demo app, __chattr__. + +## redis + +You’ll need to make sure you have a redis server running in order to use the application see the [Redis Quick Start](http://redis.io/topics/quickstart) for information on installing redis. + +## Install + +The fastest way to get __chattr__ up and running: + + * On Mac or Linux, make sure you have [nodejs][nodejs] and [npm][npm] installed + +``` +git clone git@github.com:dan-nl/realtimewebnode.git +cd realtimewebnode +npm install +npm start +``` \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..d8adf16 --- /dev/null +++ b/app.js @@ -0,0 +1,77 @@ +var express = require('express'); +var app = express(); +var http = require('http'); +var server = http.createServer(app); +var io = require('socket.io').listen(server); +var redis = require('redis'); +var redisClient = redis.createClient(); + +server.listen(8080); + +app.get('/', function (req, res) { + res.sendfile(__dirname + '/index.html'); +}); + +redisClient.on('error', function(err) { console.log( 'error : ' + err ); }); + +var storeMessage = function( name, data ) { + + var message = JSON.stringify({name:name, data:data}); + + // store up to 10 messages + redisClient.lpush('messages', message, function(error, response){ + redisClient.ltrim('messages', 0, 10); + }); + +}; + +io.sockets.on( 'connection', function ( client ) { + + client.on( 'join', function( name ) { + + client.set( 'nickname', name ); + client.broadcast.emit( 'add chatter', name ); // tell other chatters about this new chatter + redisClient.sadd( 'chatters', name ); // add the new chatter to the redis chatter set + + // add all current chatters to the current client’s chatters list + redisClient.smembers( 'chatters', function( error, names ) { + names.forEach( function( name ) { + client.emit( 'add chatter', name ); + }); + }); + + // add latest chat messages to current client + redisClient.lrange( 'messages', 0, -1, function( error, messages ) { + + messages = messages.reverse(); + + messages.forEach( function( message ) { + message = JSON.parse( message ); + client.emit( 'messages',message.name + ' : ' + message.data ); + }); + + }); + + }); + + + client.on( 'messages', function( message ) { + + client.get('nickname',function( error, name ) { + storeMessage( name, message ); + client.broadcast.emit( 'messages', name + ' : ' + message ); + }); + + }); + + + client.on( 'disconnect', function( name ) { + + client.get( 'nickname', function( error, name ) { + client.broadcast.emit( 'remove chatter', name ); + redisClient.srem( 'chatters', name ); + }); + + }); + +}); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..1be54bd --- /dev/null +++ b/index.html @@ -0,0 +1,106 @@ + + + + +chattr + + + +

chattr

+ + +
+ +
+
+ +
+ + + + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..6fe6cef --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "chattr", + "description": "A simple chat server based on the Real Time Web with Node.js codeschool class.", + "version": "0.1.0", + "author": { + "name": "dan entous", + "email": "contact@pennlinepublishing.com" + }, + "contributors": [ + { + "name": "dan entous", + "email": "contact@pennlinepublishing.com" + } + ], + "dependencies": { + "express": "3.1.0", + "redis": "0.8.2", + "socket.io": "0.9.14" + }, + "repository": { + "type": "git", + "url": "git://github.com/dan-nl/realtimewebnode.git" + }, + "scripts": { + "start": "node app.js" + }, + "readme": "# Real Time Web With Node.js\n\nThis is the code for the [Real Time Web with Node.js](http://www.codeschool.com/courses/real-time-web-with-nodejs) demo app.\n\n## redis\n\nYou’ll need to make sure you have a redis server running in order to use the application see the [Redis Quick Start](http://redis.io/topics/quickstart) for information on installing redis.\n\n## Install\n\nThe fastest way to get __chattr__ up and running:\n\n * On Mac or Linux, make sure you have [nodejs][nodejs] and [npm][npm] installed\n\n```\ngit clone git@github.com:dan-nl/realtimewebnode.git\ncd realtimewebnode\nnpm install\nnpm start\n```", + "readmeFilename": "Readme.md", + "_id": "chattr@0.1.0", + "_from": "chattr@" +} From 78539d36a38338348d512569ede447be48363f09 Mon Sep 17 00:00:00 2001 From: "dan.entous" Date: Wed, 10 Apr 2013 04:28:13 +0200 Subject: [PATCH 2/5] adjusting the readme.md --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ce944a6..df747ae 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Real Time Web With Node.js -This is the code for the [Real Time Web with Node.js](http://www.codeschool.com/courses/real-time-web-with-nodejs) demo app, __chattr__. +This is the code for the [Real Time Web with Node.js][realtime] demo app, __chattr__. ## redis -You’ll need to make sure you have a redis server running in order to use the application see the [Redis Quick Start](http://redis.io/topics/quickstart) for information on installing redis. +You’ll need to make sure you have a redis server running in order to use the application see the [Redis Quick Start][redis] for information on installing redis. ## Install @@ -17,4 +17,9 @@ git clone git@github.com:dan-nl/realtimewebnode.git cd realtimewebnode npm install npm start -``` \ No newline at end of file +``` + +[nodejs]: http://nodejs.org/ +[npm]: http://npmjs.org/ +[redis]: http://redis.io/topics/quickstart +[realtime]: http://www.codeschool.com/courses/real-time-web-with-nodejs \ No newline at end of file From 6a60d3ce9b55abe7aae49de2b8ee66bc21659bef Mon Sep 17 00:00:00 2001 From: TJ Krusinski Date: Sun, 2 Mar 2014 16:15:46 -0500 Subject: [PATCH 3/5] update versions --- .gitignore | 1 + package.json | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package.json b/package.json index 6fe6cef..7ba0a40 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ } ], "dependencies": { - "express": "3.1.0", - "redis": "0.8.2", - "socket.io": "0.9.14" + "redis": "^0.10.1", + "express": "^3.4.8", + "socket.io": "^0.9.16" }, "repository": { "type": "git", From 1a2936b05b4dfe09c7a10c996fc9c401418ece74 Mon Sep 17 00:00:00 2001 From: TJ Krusinski Date: Sun, 2 Mar 2014 16:38:31 -0500 Subject: [PATCH 4/5] revise app for update --- app.js | 113 ++++++++++++++++++++++++++++----------------- index.html | 110 ++++++------------------------------------- lib/redisClient.js | 8 ++++ public/app.css | 23 +++++++++ public/app.js | 56 ++++++++++++++++++++++ 5 files changed, 171 insertions(+), 139 deletions(-) create mode 100644 lib/redisClient.js create mode 100644 public/app.css create mode 100644 public/app.js diff --git a/app.js b/app.js index d8adf16..9f164df 100644 --- a/app.js +++ b/app.js @@ -1,77 +1,106 @@ var express = require('express'); var app = express(); -var http = require('http'); -var server = http.createServer(app); +var server = require('http').createServer(app); var io = require('socket.io').listen(server); -var redis = require('redis'); -var redisClient = redis.createClient(); +var redisClient = require('./lib/redisClient.js'); -server.listen(8080); +var port = process.env.PORT || 8000; +server.listen(port); +console.log('Server listening on port %d', port); -app.get('/', function (req, res) { +/** + * Serve static files from `public` + */ + +app.use(express.static(__dirname + '/public')); + +/** + * Handle all routes to the webserver + */ + +app.get('/*', function (req, res) { res.sendfile(__dirname + '/index.html'); }); -redisClient.on('error', function(err) { console.log( 'error : ' + err ); }); - -var storeMessage = function( name, data ) { +/** + * Store a message in redis + * + * @function storeMessage + * @param {String} name + * @param {Object} data + */ +function storeMessage (name, data) { var message = JSON.stringify({name:name, data:data}); // store up to 10 messages - redisClient.lpush('messages', message, function(error, response){ + redisClient.lpush('messages', message, function(error) { + if (error) throw error; redisClient.ltrim('messages', 0, 10); }); - }; -io.sockets.on( 'connection', function ( client ) { +/** + * Handle connnection Websockets + */ - client.on( 'join', function( name ) { +io.sockets.on('connection', function (client) { - client.set( 'nickname', name ); - client.broadcast.emit( 'add chatter', name ); // tell other chatters about this new chatter - redisClient.sadd( 'chatters', name ); // add the new chatter to the redis chatter set - // add all current chatters to the current client’s chatters list - redisClient.smembers( 'chatters', function( error, names ) { - names.forEach( function( name ) { - client.emit( 'add chatter', name ); + /** + * When users join, set their nickname and broadcast they are here + * Add the user to redis set `chatters` + */ + + client.on('join', function(name) { + client.set('nickname', name); + client.broadcast.emit('add chatter', name); + redisClient.sadd('chatters', name); + + /** + * Add all current chatters to the current client’s chatters list + */ + + redisClient.smembers('chatters', function(error, names) { + names.forEach(function(name) { + client.emit('add chatter', name); }); }); - // add latest chat messages to current client - redisClient.lrange( 'messages', 0, -1, function( error, messages ) { - + /** + * Add latest chat messages to current client + */ + + redisClient.lrange('messages', 0, -1, function( error, messages) { messages = messages.reverse(); - messages.forEach( function( message ) { - message = JSON.parse( message ); - client.emit( 'messages',message.name + ' : ' + message.data ); + messages.forEach(function(message) { + message = JSON.parse(message); + client.emit('messages',message.name + ' : ' + message.data); }); - }); - }); + /** + * When a message comes through, get the name and broadcast the messsage + * Store the message after we get the nicname + */ - client.on( 'messages', function( message ) { - - client.get('nickname',function( error, name ) { - storeMessage( name, message ); - client.broadcast.emit( 'messages', name + ' : ' + message ); + client.on('messages', function(message) { + client.get('nickname',function(error, name) { + storeMessage(name, message); + client.broadcast.emit('messages', name + ' : ' + message); }); - }); + /** + * When a user disconnects, get their name and broadcast they left + */ - client.on( 'disconnect', function( name ) { - - client.get( 'nickname', function( error, name ) { - client.broadcast.emit( 'remove chatter', name ); - redisClient.srem( 'chatters', name ); + client.on('disconnect', function(name) { + client.get('nickname', function(error, name) { + client.broadcast.emit('remove chatter', name); + redisClient.srem('chatters', name); }); - }); - -}); \ No newline at end of file +}); diff --git a/index.html b/index.html index 1be54bd..7dd3b04 100644 --- a/index.html +++ b/index.html @@ -1,106 +1,22 @@ - - -chattr - - - -

chattr

+ + chattr + + + +

chattr

    -
    +
    - - - - - - - \ No newline at end of file + + + + + + diff --git a/lib/redisClient.js b/lib/redisClient.js new file mode 100644 index 0000000..734e6c5 --- /dev/null +++ b/lib/redisClient.js @@ -0,0 +1,8 @@ +var redis = require('redis'); +var redisClient = redis.createClient(); + +redisClient.on('error', function(err) { + console.log( 'error : ' + err ); +}); + +module.exports = redisClient; diff --git a/public/app.css b/public/app.css new file mode 100644 index 0000000..5f58f7d --- /dev/null +++ b/public/app.css @@ -0,0 +1,23 @@ +body { font-family: sans-serif; color: #333; } + +#chatters { width: 100px; margin: 0 1em 0 0; float: left; list-style: none; } + +#chatters, #chat-console { height: 300px; overflow: auto; padding: 1%;} + +#chat-console, #chatters, #chat-form input[type=text] { border: 1px solid #ccc; } + +#chat-console, #chat-form { margin-right: 7%; } + +#chat-form { margin-top: 1em; text-align: right; clear: both; } + +#chat-form input[type=text] { width: 80%; font-size: 120%; padding: 1%; } + +.connected { color: #8b0000; } + +/* http://hellohappy.org/css3-buttons/ */ +input[type=submit] { background-color: #eeeeee; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #cccccc)); background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); background-image: -o-linear-gradient(top, #eeeeee, #cccccc); background-image: linear-gradient(top, #eeeeee, #cccccc); border: 1px solid #ccc; border-bottom: 1px solid #bbb; border-radius: 3px; color: #333; font-size: 100%; padding: 8px 0; text-align: center; text-shadow: 0 1px 0 #eee; width: 150px; } + +input[type=submit]:hover { background-color: #dddddd; background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #dddddd), color-stop(100%, #bbbbbb)); background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); background-image: linear-gradient(top, #dddddd, #bbbbbb); border: 1px solid #bbb; border-bottom: 1px solid #999; cursor: pointer; text-shadow: 0 1px 0 #ddd; } + +input[type=submit]:active { border: 1px solid #aaa; border-bottom: 1px solid #888; -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; } + diff --git a/public/app.js b/public/app.js new file mode 100644 index 0000000..ed39a18 --- /dev/null +++ b/public/app.js @@ -0,0 +1,56 @@ +;(function(){ + + var socket = io.connect(); + var chatters = document.getElementById('chatters'); + var chat_input = document.getElementById('chat-input'); + var chat_console = document.getElementById('chat-console'); + var nickname; + + function removeChatter(name) { + var current_chatters = document.querySelectorAll('[data-name]'), + i; + + for (var i = 0; i < current_chatters.length; i += 1) { + if (name === current_chatters[i].getAttribute('data-name')) { + current_chatters[i].parentNode.removeChild(current_chatters[i]); + break; + }; + }; + }; + + function insertChatter(name) { + var new_chatter = document.createElement('li'); + new_chatter.setAttribute('data-name', name); + new_chatter.setAttribute('class', 'connected'); + new_chatter.innerHTML = name; + chatters.appendChild(new_chatter); + }; + + function insertMessage(message) { + var new_message = document.createElement('span'); + new_message.innerHTML = message + '
    '; + chat_console.appendChild(new_message); + }; + + document.getElementById('chat-form').onsubmit = function(e) { + e.preventDefault(); + socket.emit('messages', chat_input.value); + insertMessage(nickname + ' : ' + chat_input.value); + chat_input.value = null; + }; + + socket.on('messages', function(data) { + insertMessage(data); + }); + + socket.on('connect', function(data) { + chat_console.innerHTML = 'connected to the chat socket
    '; + nickname = prompt('what is your nickanme?'); + socket.emit('join', nickname); + }); + + socket.on('add chatter', insertChatter); + socket.on('remove chatter', removeChatter); + +}()); + From dfa7416f612038ab2f4e28110272d0a5ed8023d5 Mon Sep 17 00:00:00 2001 From: TJ Krusinski Date: Sun, 2 Mar 2014 16:42:43 -0500 Subject: [PATCH 5/5] update readme --- README.md | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index df747ae..db68ccc 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,12 @@ This is the code for the [Real Time Web with Node.js][realtime] demo app, __chattr__. -## redis +## Getting Started -You’ll need to make sure you have a redis server running in order to use the application see the [Redis Quick Start][redis] for information on installing redis. +To run the server you'll need [Node.js](http://nodejs.org) and [Redis](http://redis.io) installed. Then run the following commands: -## Install +1. `$ npm install` +1. `$ redis-server &` +1. `$ node app.js` -The fastest way to get __chattr__ up and running: - - * On Mac or Linux, make sure you have [nodejs][nodejs] and [npm][npm] installed - -``` -git clone git@github.com:dan-nl/realtimewebnode.git -cd realtimewebnode -npm install -npm start -``` - -[nodejs]: http://nodejs.org/ -[npm]: http://npmjs.org/ -[redis]: http://redis.io/topics/quickstart -[realtime]: http://www.codeschool.com/courses/real-time-web-with-nodejs \ No newline at end of file +At this point you will be able to go to the address `http://localhost:8000/` in your web browser to interact with the app.