var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, usernames = {}
, messages = []
, port = 8080;
io.set('log level', 0); // disable log message in console
io.set('transports', [
'xhr-polling'
, 'jsonp-polling'
, 'websocket'
, 'flashsocket'
, 'htmlfile'
]);
app.listen(port);
// need helper for log
// app.debug_log = function(log) { console.log(data); }
var socket_users = {};
function session_id_from_request(request) {
var cookies = {};
request.headers.cookie && request.headers.cookie.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
console.log('key: ' + parts[ 0 ].trim() );
console.log('value: ' + parts[ 1 ].trim() );
//cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});
}
function get_sid(str_cookie) {
var SID = '';
str_cookie.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
if (parts[ 0 ].trim() === 'SID') {
SID = parts[ 1 ].trim();
}
});
return SID;
}
function handler (req, res) {
//get_cookie(req);
//console.log(req.url);
//console.log(req.headers);
var mime_type = 'text/html';
var file = __dirname + '/index.html';
if (req.url === '/app.css') {
var file = __dirname + '/app.css';
mime_type = 'text/css';
}
if (req.url === '/app.js') {
var file = __dirname + '/app.js';
mime_type = 'application/javascript';
}
if (req.url === '/favicon.ico') {
res.writeHead(200, {'Content-Type': 'text/plain'});
return res.end('faivicon.ico');
}
fs.readFile(file, function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200, {
'Content-Type': mime_type,
'Content-Length': data.length
});
res.end(data);
});
/*
console.log((new Date()) + ' HTTP server. URL' + request.url + ' requested.');
if (request.url === '/status') {
response.writeHead(200, {'Content-Type': 'application/json'});
var responseObject = {
currentClients: clients.length,
totalHistory: history.length
}
response.end(JSON.stringify(responseObject));
} else {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.end('Sorry, unknown url');
}
*/
//http://martinsikora.com/nodejs-and-websocket-simple-chat-tutorial
}
function html_escape(str) {
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
}
io.sockets.on('connection', function (socket) {
//var cookie = socket.handshake.headers['cookie'];
// console.log(cookie);
//console.log(socket.id); // this id is random generated for each connection
//console.log(socket.namespace.manager.handshaken);
// socket.session_id = get_sid(socket.handshake.headers['cookie']);
//console.log('Session ID: ' + socket.session_id);
console.log(socket.id);
if ( socket_users[socket.id] !== undefined ) {
socket.username = socket_users[socket.id].username;
socket_users[socket.id].id = socket.id;
//socket.emit('resumechat', 'Admin', socket_users[socket.session_id] + ' comes back to chat');
socket.emit('updateusers', usernames);
socket.emit('loadmessage', messages);
socket.emit('updatechat', 'Admin', 'Your chat has been resumed.');
}
// when the client emits 'sendchat', this listens and executes
socket.on('resume', function (id) {
console.log('Resume chat for socket id: ' + id);
if ( socket_users[id] !== undefined ) {
socket.username = socket_users[id].username;
//update new id
socket_users[id].id = socket.id;
//socket.emit('resumechat', 'Admin', socket_users[socket.session_id] + ' comes back to chat');
socket.emit('updateusers', usernames);
socket.emit('loadmessage', messages);
socket.emit('updatechat', 'Admin', 'Your chat has been resumed.');
}
else {
console.log('User not found, trigger create new user, update cookie to current socket id');
socket.emit('register', {refer: 'resume'});
}
//else, trigger new user
});
socket.on('sendchat', function (data) {
data = html_escape(data);
var created = new Date();
// we tell the client to execute 'updatechat' with 2 parameters
var message = {username: socket.username, data: data, created: created.getTime()};
messages.push(message);
//io.sockets.emit('updatechat', socket.username, data);
// to all user include this user
io.sockets.emit('newmessage', message);
});
// add user
socket.on('adduser', function(username) {
// we store the username in the socket session for this client
socket_users[socket.id] = { username: username, id: socket.id };
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
socket.emit('loadmessage', messages);
socket.emit('updateusers', usernames);
// echo to client they've connected
socket.emit('updatechat', 'Admin', 'Hello ' + username +', welcome to chat.');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatechat', 'Admin', username + ' has join to chat room');
// update the list of users in chat, client-side
// io.sockets.emit('loadmessage', messages);
// io.sockets.emit('updateusers', usernames);
//update for other clients
socket.broadcast.emit('updateusers', usernames);
});
// end add user
//disconnect
// when the user disconnects. perform this
socket.on('disconnect', function() {
// need to check user has resummed chat, socket_id does not updated
if ( socket_users[socket.id] !== undefined && socket_users[socket.id].id === socket.id) {
delete socket_users[socket.id];
// remove the username from global usernames list
delete usernames[socket.username];
console.log('Delete user ' + socket.username);
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatechat', 'Admin', socket.username + ' has left chat room');
}
});
//end disconnect
});
//http://psitsmike.com/2011/09/node-js-and-socket-io-chat-tutorial
//http://psitsmike.com/2011/10/node-js-and-socket-io-multiroom-chat-tutorial
//http://net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with-nodejs-socket-io-and-expressjs/
//http://socket.io/#how-to-use
//http://davidwalsh.name/websocket
//http://www.stoimen.com/blog/2010/12/02/diving-into-node-js-a-long-polling-example
//http://www.contentwithstyle.co.uk/content/long-polling-example-with-nodejs/
//http://book.mixu.net/ch3.html
//http://stackoverflow.com/questions/13329129/nodejs-long-polling-pushing-rejeverse-ajax-what-do-i-need-to-push-live-data-i
//https://go-left.com/blog/programming/long-polling-with-node-js/
//http://www.gianlucaguarini.com/blog/nodejs-and-a-simple-push-notification-server/
//http://blog.nemikor.com/2010/05/21/long-polling-in-nodejs/
//https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsISocketTransportService
|