I've built a simple chat server/client on Node.js and socket.io that I would like reviewed. My main concern is making the chat.js (client) running as cleanly as possible (OO) and streamlining data back and forth so I can add client monitoring (updated list of connected users) features down the line without issue.
Aside from that, I'm open to any critique/feedback about these sections of code on best practices or design patterns. This project is mostly for learning an unfamiliar technology (socket.io and, somewhat, node.js).
Here is the server code:
server.js:
var express = require('express');
var app = express();
var PORT = 7029;
var APPNAME = "Hermes";
//Set Views
app.set('views', __dirname + '/templates');
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express);
app.get('/', function(req,res) {
res.render('page');
});
//Setup server
app.use(express.static(__dirname + '/public'));
var io = require('socket.io').listen(app.listen(PORT));
io.set('transports', ['xhr-polling']);
console.log('Listening on port ' + PORT);
//Event Handlers
io.sockets.on('connection', function(socket) {
welcome = new Message("Welcome to the ZeroDae chat service.", APPNAME);
socket.emit('message', welcome );
socket.on('send', function(data) {
message = new Message(data.content, data.user);
io.sockets.emit('message', message);
});
socket.on('join', function(data) {
join = new Message(data + " has joined the chat.", APPNAME);
io.sockets.emit('message', join);
});
socket.on('disconnect', function() {
leaving = new Message("Someone has left.", APPNAME);
io.sockets.emit('message', leaving);
});
});
function Message(content, user) {
this.content = content;
this.user = user;
}
Here is the chat client:
chat.js:
$(document).ready(function () {
var messages = [];
var socket = io.connect('http://chat.zerodaedalus.com');
var field = $('#field');
var send = $('#send');
var content = $('#content');
var current = $('#current');
var warning = $('#browserWarning');
var user = getUser();
var username = $('#username');
var update = $('#update');
var id;
function User() {
}
//Hide warning
warning.hide();
//set username and display it on screen
username.val(user);
currentUser();
//event handlers
send.click(submit);
update.click(setUser);
field.keyup(function (e) {
if(e.which === 13) {
submit();
}
});
username.keyup(function (e) {
if(e.which === 13) {
setUser();
}
});
socket.on('message', function(data) {
if(data.content) {
if(data.user === 'Hermes')
classes = 'message text-muted ';
else
classes = 'message ';
content
.append('<p></p>')
.find('p:last-child')
.addClass(classes + id)
.append('<span></span>')
.find('span:last-child')
.addClass('user')
.text(data.user + ': ')
.closest('.message')
.append('<span></span>')
.find('span:last-child')
.addClass('content')
.text(data.content)
}
else {
console.log('There is a problem:', data);
}
});
function getUser() {
if(typeof(Storage) !== "undefined") {
if(localStorage.getItem('username'))
name = localStorage.getItem('username');
else
name = generateUsername();
}
else {
warning.show();
}
return name;
}
function setUser() {
localStorage.setItem('username', username.val() );
if(username.val() === '')
user = generateUsername();
else
user = username.val();
currentUser();
}
function generateUsername() {
return 'zd-' + Math.floor((Math.random() * 729) + 1);
}
function currentUser() {
current.html(' (Currently: ' + user + ')');
socket.emit('join', user);
console.log(user);
}
function submit() {
var text = $('#field').val();
socket.emit('send', { content: text, user: user });
field.val('');
content.animate({scrollTop: content.prop('scrollHeight')});
}
});