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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
npm-debug.log
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node app.js
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Real Time Web With Node.js
# RealTime 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 is bases on 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 chattr. See the [Redis Quick Start][redis] for information on installing redis.

## install

The fastest way to get __chattr__ up and running:

* 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
109 changes: 109 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*jslint node: true, nomen: true, unparam: true, white: true */
(function() {

'use strict';

var redisToGo,
redis,
redisClient,
storeMessage,
express = require( 'express' ),
app = express(),
http = require( 'http' ),
server = http.createServer( app ),
io = require( 'socket.io' ).listen( server ),
path = require( 'path' ),
port = Number( process.env.PORT || 8080 ),
max_messages = 100;

server.listen( port, function() {
console.log( "Listening on " + port );
});

app.use( express.static( path.join( __dirname, 'public' ) ) );

app.get('/', function ( req, res ) {
res.sendfile( __dirname + '/index.html' );
});

if ( process.env.REDISTOGO_URL ) {
redisToGo = require( 'url' ).parse( process.env.REDISTOGO_URL );
redis = require( 'redis' );
redisClient = redis.createClient( redisToGo.port, redisToGo.hostname );
redisClient.auth( redisToGo.auth.split( ':' )[1] );
} else {
redis = require( 'redis' );
redisClient = redis.createClient();
}

redisClient.ping( function( reply ) {
if ( reply !== null && reply.indexOf( 'ECONNREFUSED' ) > -1 ) {
console.log( 'error: cannot connect with the redis server' );
process.exit( 'error: cannot connect with the redis server' );
}
});

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

storeMessage = function( name, data ) {
var message = JSON.stringify({
name:name,
data:data
});

// store up to max_messages
redisClient.lpush( 'messages', message, function( error, response ) {
redisClient.ltrim( 'messages', 0, max_messages );
});
};

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 ) {
if ( message.indexOf( 'udacity' ) > -1 ) {
client.broadcast.emit( 'messages', name + ' : ' + '<p>Education is no longer a one-time event but a lifelong experience. Education should be less passive listening (no long lectures) and more active doing. Education should empower students to succeed not just in school but in life.</p><p>We are reinventing education for the 21st century by bridging the gap between real-world skills, relevant education, and employment. Our students will be fluent in new technology, modern mathematics, science, and critical thinking. They will marry skills with creativity and humanity to learn, think, and do. Udacians are curious and engaged world citizens.</p><p>Interested in working with us? View our openings.</p>' );
} else {
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 );
});
});

client.on( 'flushall', function() {
redisClient.flushall();
});
});

}());
34 changes: 34 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "chattr",
"version": "0.1.0",
"description": "A simple chat server based on the Real Time Web with Node.js codeschool class.",
"author": {
"name": "dan entous",
"email": "contact@pennlinepublishing.com"
},
"repository": {
"type": "git",
"url": "https://github.com/dan-nl/realtimewebnode.git"
},
"homepage": "https://github.com/dan-nl/realtimewebnode",
"license": "GPLv3",
"keywords": [
"codeschool",
"websockets",
"chat"
],
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"engines": {
"node": "0.10.26"
},
"dependencies": {
"express": "3.1.0",
"redis": "0.8.2",
"socket.io": "0.9.14"
},
"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"
}
93 changes: 93 additions & 0 deletions public/css/css.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
html {
font-family: sans-serif;
font-size: 16px;
}

body {
font-size: 100%;
color: #333;
padding: 3%;
}

h1 {
margin-top: 0;
}

#chatters {
width: 24%;
max-width: 100px;
margin: 0 2% 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-form {
margin-top: 1em;
text-align: right;
clear: both;
}

#chat-form input[type = text] {
width: 98%;
font-size: 120%;
padding: 1%;
margin: 0;
}

.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;
margin: 1% 0 0 0;
color: #333;
font-size: 100%;
padding: 7px 18px;
text-align: center;
text-shadow: 0 1px 0 #eee;
}

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;
}
23 changes: 23 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link href="css/css.css" rel="stylesheet" />
<title>chattr</title>
</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/><br/>
<input type="submit" value="send"/>
</form>

<script src="/socket.io/socket.io.js"></script>
<script src="js/js.js"></script>

</body>
</html>
86 changes: 86 additions & 0 deletions public/js/js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*global console, io, prompt */
/*jslint browser: true, white: true */
(function() {

'use strict';


if ( window.io === undefined ) {
console.log( 'oops ... socket.io did’t load' );
return;
}


var chattr = {

nickname: undefined,
server: io.connect(
'//' +
window.location.hostname +
( window.location.port ? ':' + window.location.port : '' )
),
chatters: document.getElementById( 'chatters' ),
chat_form: document.getElementById( 'chat-form' ),
chat_input: document.getElementById( 'chat-input' ),
chat_console: document.getElementById( 'chat-console' ),


handleFormSubmit: function( evt ) {
evt.preventDefault();
chattr.server.emit( 'messages', chattr.chat_input.value );
chattr.insertMessage( chattr.nickname + ' : ' + chattr.chat_input.value );

if ( chattr.chat_input.value === 'flushall' ) {
chattr.server.emit( 'flushall' );
}

chattr.chat_input.value = null;
},

handleServerConnect: function() {
chattr.chat_console.innerHTML = '<span class="connected">connected to the chat server</span><br/>';
chattr.nickname = prompt( 'what is your nickanme?' );
chattr.server.emit( 'join', chattr.nickname );
},

init: function() {
chattr.chat_form.addEventListener( 'submit', chattr.handleFormSubmit, false );
chattr.server.on( 'messages', chattr.insertMessage );
chattr.server.on( 'connect', chattr.handleServerConnect );
chattr.server.on( 'add chatter', chattr.insertChatter );
chattr.server.on( 'remove chatter', chattr.removeChatter );
},

insertChatter: function( name ) {
var new_chatter = document.createElement('li');
new_chatter.setAttribute( 'data-name', name );
new_chatter.setAttribute( 'class', 'connected' );
new_chatter.innerHTML = name;
chattr.chatters.appendChild( new_chatter );
},

insertMessage: function( message ) {
var new_message = document.createElement('span');
new_message.innerHTML = message + '<br/>';
chattr.chat_console.appendChild( new_message );
chattr.chat_console.scrollTop = chattr.chat_console.scrollHeight;
},

removeChatter: function( name ) {
var i,
current_chatters = document.querySelectorAll( '[data-name]' ),
ii = current_chatters.length;

for ( i = 0; i < ii; i += 1 ) {
if ( name === current_chatters[i].getAttribute( 'data-name' ) ) {
current_chatters[i].parentNode.removeChild( current_chatters[i] );
break;
}
}
}

};

chattr.init();

}());