Created
July 20, 2012 17:16
-
-
Save tresbailey/3151970 to your computer and use it in GitHub Desktop.
Chat App using nodejs for server, socket.io for passing messages to/from the browser, coffeescript for some server-side files (for now), node-redis for persisting chats, express(node) for http wrapping, and jade for templating (for now), and backbone for
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var NodeChatController = { | |
init: function() { | |
this.socket = io.connect('http://localhost'); | |
var mysocket = this.socket; | |
this.model = new models.NodeChatModel(); | |
this.view = new NodeChatView({model: this.model, socket: this.socket, el: $('#content')}); | |
var view = this.view; | |
this.socket.on('message', function(msg) { | |
console.log('msg rcved'+msg); | |
view.msgReceived($.parseJSON(msg)) | |
}); | |
this.view.render(); | |
return this; | |
} | |
}; | |
$(document).ready(function () { | |
window.app = NodeChatController.init(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!!! 5 | |
html(lang="en") | |
head | |
title nodechat | |
script(type="text/javascript", src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js") | |
script(type="text/javascript", src="lib/underscore.js") | |
script(type="text/javascript", src="lib/backbone.js") | |
script(type="text/javascript", src="/socket.io/socket.io.js") | |
script(type="text/javascript", src="models.js") | |
script(type="text/javascript", src="views/views.js") | |
script(type="text/javascript", src="controllers/controller.js") | |
body | |
#heading | |
h1 nodechat | |
#content | |
p | |
| connected clients | |
span#client_count 0 | |
p | |
| Fun Chat Messages | |
ul#chat_list | |
form(method="post", action="#", onsubmit="return false;")#messageForm | |
p | |
label Name: | |
input(type="text", name="user_name") | |
p | |
label Message: | |
input(type="text", name="message") | |
input(type="submit", value="send") | |
#footer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ChatView = Backbone.View.extend({ | |
tagName: 'li', | |
initialize: function(options) { | |
_.bindAll(this, 'render'); | |
this.model.bind('all', this.render); | |
}, | |
render: function() { | |
$(this.el).html( this.model.get("name") + ": " + this.model.get("text")); | |
return this; | |
} | |
}); | |
var ClientCountView = Backbone.View.extend({ | |
initialize: function(options) { | |
_.bindAll(this, 'render'); | |
this.model.bind('all', this.render); | |
}, | |
render: function() { | |
$(this.el).html(" -> " + this.model.get('clients')); | |
return this; | |
} | |
}); | |
var NodeChatView = Backbone.View.extend({ | |
initialize: function(options) { | |
this.model.chats.bind('add', this.addChat); | |
this.socket = options.socket; | |
this.clientCountView = new ClientCountView({ model: new models.ClientCountModel(), | |
el: $('#client_count') | |
}); | |
}, | |
events: { | |
"submit #messageForm": "sendMessage" | |
}, | |
addChat: function(chat) { | |
var view = new ChatView({ model: chat }); | |
$('#chat_list').append(view.render().el); | |
}, | |
msgReceived: function(message) { | |
switch(message.event) { | |
case 'initial': | |
this.model.mport(message.data); | |
break; | |
case 'chat': | |
var newChatEntry = new models.ChatEntry(); | |
newChatEntry.mport(message.data); | |
this.model.chats.add(newChatEntry); | |
break; | |
case 'update': | |
this.clientCountView.model.mport(message.data); | |
break; | |
} | |
}, | |
sendMessage: function(e) { | |
var inputField = $('input[name=message]'); | |
var nameField = $('input[name=user_name]'); | |
console.log(inputField); | |
var chatEntry = new models.ChatEntry({ name: nameField.val(), | |
text: inputField.val() | |
}); | |
this.socket.send(JSON.stringify(chatEntry.xport())); | |
inputField.val(''); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app = require('express').createServer() | |
jade = require 'jade' | |
_ = require('underscore')._ | |
Backbone = require 'backbone' | |
redis = require 'redis' | |
rc = redis.createClient() | |
models = require './models' | |
$ = require('jquery') | |
app.set 'view engine', 'jade' | |
app.set 'view options', {layout: false} | |
app.listen 4000 | |
app.get '/*.(js|css)', (req, res) -> | |
res.sendfile "./#{ req.url}" | |
app.get '/', (req, res) -> | |
res.render 'index' | |
activeClients = 0 | |
clientCountModel = new models.ClientCountModel {clients: activeClients} | |
nodeChatModel = new models.NodeChatModel() | |
rc.lrange 'chatentries', -10, -1, (err, data) -> | |
if data | |
_.each data, (jsonChat) -> | |
chat = new models.ChatEntry() | |
chat.mport jsonChat | |
nodeChatModel.chats.add chat | |
console.log "Revived #{ JSON.stringify nodeChatModel.chats } chats" | |
else | |
console.log "No data returned for key" | |
io = require('socket.io').listen app | |
io.sockets.on 'connection', (client) -> | |
console.log "client count mode: #{ JSON.stringify clientCountModel }" | |
clientCountModel.incrClients() | |
console.log "client count mode: #{ JSON.stringify clientCountModel }" | |
client.on 'disconnect', () -> clientDisconnect(client) | |
client.on 'message', (msg) -> chatMessage(client, io, msg) | |
console.log "all clients are #{ JSON.stringify nodeChatModel.xport() }" | |
client.send JSON.stringify({ | |
event: 'initial', | |
data: nodeChatModel.xport() | |
}) | |
io.sockets.send JSON.stringify({ | |
event: 'update', | |
data: clientCountModel.xport() | |
}) | |
chatMessage = (client, socket, msg) -> | |
chat = new models.ChatEntry() | |
console.log "importing chat #{JSON.parse msg }" | |
chat.mport JSON.parse(msg) | |
console.log "imported chat #{ chat.get('name') }" | |
rc.incr 'next.chatentry.id', (err, newId) -> | |
chat.set {id: newId} | |
nodeChatModel.chats.add chat | |
console.log "(#{ client.sessionId}) #{ chat.get('id') } #{ chat.get('name') }: #{ chat.get('text') }" | |
rc.lpush 'chatentries', chat.xport(), redis.print | |
rc.bgsave() | |
console.log "socket increment with #{ JSON.stringify chat }" | |
emission = { event: 'chat', data: chat.xport() } | |
console.log "emitting #{ JSON.stringify emission }" | |
client.broadcast.send JSON.stringify(emission) | |
clientDisconnect = (client) -> | |
activeClients -= 1 | |
io.sockets.send JSON.stringify({ | |
event: 'update', | |
data: clientCountModel.xport() | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is taken from http://fzysqr.com/2011/02/28/nodechat-js-using-node-js-backbone-js-socket-io-and-redis-to-make-a-real-time-chat-app/ and brings it more up to date (plus makes it work). Some prerequisites to running it, though. You'll need to install coffeescript, which will also install nodejs. After that, you can use node's package manager (npm) to install some of the other js modules. For instance, do: npm install express to install the [email protected] module (which is broken for the latest release). You can use npm for getting local copies of jquery, backbone, etc. Anything you want to use on the client side that you install from npm should be copied from its location in the node_modules folder into a separate lib folder (see the imports on index.jade). Also, the jade and views.js files should be put into a views folder, as well as moving controllers.js into its own folder. No real reason for this, except thats just where i've got the includes looking for them in the jade template.