Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 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][realtime] demo app, __chattr__.

## Getting Started

To run the server you'll need [Node.js](http://nodejs.org) and [Redis](http://redis.io) installed. Then run the following commands:

1. `$ npm install`
1. `$ redis-server &`
1. `$ node app.js`

At this point you will be able to go to the address `http://localhost:8000/` in your web browser to interact with the app.
106 changes: 106 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var redisClient = require('./lib/redisClient.js');

var port = process.env.PORT || 8000;
server.listen(port);
console.log('Server listening on port %d', port);

/**
* 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');
});

/**
* 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) {
if (error) throw error;
redisClient.ltrim('messages', 0, 10);
});
};

/**
* Handle connnection Websockets
*/

io.sockets.on('connection', function (client) {


/**
* 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) {
messages = messages.reverse();

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);
});
});

/**
* 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);
});
});
});
22 changes: 22 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<title>chattr</title>
<link rel="stylesheet" href="/app.css">
</head>
<body>
<h1>chattr</h1>

<ul id="chatters"></ul>
<div id="chat-console"></div>

<form id="chat-form">
<input type="text" name="chat-input" id="chat-input" placeholder="type your message here ..." autofocus autocomplete="off"><br>
<input type="submit" value="send"/>
</form>

<script src="/socket.io/socket.io.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/app.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions lib/redisClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var redis = require('redis');
var redisClient = redis.createClient();

redisClient.on('error', function(err) {
console.log( 'error : ' + err );
});

module.exports = redisClient;
31 changes: 31 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -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": {
"redis": "^0.10.1",
"express": "^3.4.8",
"socket.io": "^0.9.16"
},
"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@"
}
23 changes: 23 additions & 0 deletions public/app.css
Original file line number Diff line number Diff line change
@@ -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; }

56 changes: 56 additions & 0 deletions public/app.js
Original file line number Diff line number Diff line change
@@ -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 + '<br/>';
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 = '<span class="connected">connected to the chat socket</span><br/>';
nickname = prompt('what is your nickanme?');
socket.emit('join', nickname);
});

socket.on('add chatter', insertChatter);
socket.on('remove chatter', removeChatter);

}());