Skip to content

Instantly share code, notes, and snippets.

@barrychapman
Created June 14, 2012 19:23
Show Gist options
  • Save barrychapman/2932358 to your computer and use it in GitHub Desktop.
Save barrychapman/2932358 to your computer and use it in GitHub Desktop.
stuff
var http = require('http');
var MessageHandler = function () {
// yeah yeah, functions in the constructor = bad
// but its a singleton and I'd like to keep these
// private
// non-api auth message handling function
this._auth = function (client, msg) {
session = this.session_store.get('username', msg.username);
if (session) {
this.session_store.touch(session, client);
client.send({
type: 'AUTH',
loggedin: true,
newsession: false
});
} else {
var auth_handler = this.auth_handler;
var session_store = this.session_store;
// call authentication handler
auth_handler.authenticate(client, msg, function (client, reply) {
// new session
if (reply.type == 'AUTH' && reply.status) {
// call auth friends lookup
auth_handler.friends(client, msg, function (client, msg, friends_array) {
// cycle through your friends list comparing it to active sessions
friends_dict = {};
for (i = 0; i < friends_array.length; i++) {
var username = friends_array[i]['username'];
var displayname = friends_array[i]['displayname'];
var profilepic = friends_array[i]['thumb'];
sess = session_store.get('username', username);
friends_dict[username] = [{
"displayname": displayname
}, {
"profilepic": profilepic
}, {
"status": (sess ? sess.status : ['offline', ''])
}];
if (sess) {
// notify friends you've logged on
sess.client.send({
type: 'STATUS',
username: reply.username,
displayname: reply.displayname,
profilepic: reply.thumb,
status: ['available', '']
});
}
}
// create session & notify client
session_store.create(msg.username, client, friends_array);
client.send({
type: 'AUTH',
username: reply.username,
displayname: reply.displayname,
profilepic: reply.thumb,
loggedin: true,
friends: friends_dict,
newsession: true
});
});
} else if (!reply.status) {
// authenticate failed
client.send({
type: 'AUTH',
loggedin: false
});
}
});
}
}
// send a message
this._im = function (from, to, message) {
recipient = this.session_store.get('username', to);
var host = WWW_HOST,
clen = 'data[User][username]=' + from + '&data[User][updatesession]=1',
site = http.createClient(80, host),
auth = site.request('POST', 'http://' + host + SESSION_UPDATE, {
'host': host,
'Content-Length': clen.length,
'Content-Type': 'application/x-www-form-urlencoded'
});
auth.write(clen);
auth.end();
if (recipient) {
recipient.client.send({
type: 'IM',
from: from,
message: message
});
}
}
// send typing status
this._typing = function (from, to) {
recipient = this.session_store.get('username', to);
if (recipient) {
recipient.client.send({
type: 'TYPING',
from: from
});
}
}
// update friends of a change in this sessions status
this._status = function (user, status) {
session = this.session_store.get('username', user);
session.status = status;
this.session_store.set(user, session);
for (var i = 0; i < session.friends.length; i++) {
if ( typeof session.friends[i] != 'undefined' )
friend_session = this.session_store.get('username', session.friends[i]['username']);
else
friend_session = false;
if (friend_session) {
friend_session.client.send({
type: 'STATUS',
username: user,
status: status
});
}
}
}
// send notification to user with valid session
this._notification = function (to, msg) {
recipient = this.session_store.get('username', to);
userstatus = this.session_store.get('username', msg.username);
if ( typeof recipient == "undefined" )
return;
if ( typeof userstatus == "undefined" )
usersstatus = "Available";
else
usersstatus = userstatus.status;
if (recipient) {
recipient.client.send({
type: 'NOTIFICATION',
notifytype: msg.notifytype,
id: msg.id,
username: msg.username,
displayname: msg.displayname,
profilepic: msg.profilepic,
status: usersstatus,
title: msg.title,
message: msg.message,
notifypopup: msg.notifypopup,
notifytab: msg.notifytab,
date: msg.date
});
}
if (msg.notifytype == "friendaccept" || msg.notifytype == "addfriend") {
if (typeof recipient.friends != "undefined") {
/*
recipient.friends.push({
"username": msg.username
}, {
"displayname": msg.displayname
}, {
"profilepic": msg.profilepic
});
*/
recipient.friends.push({
"username": msg.username,
"displayname": msg.displayname,
"profilepic": msg.profilepic
});
}
} else if (msg.notifytype == "friendremoved" || msg.notifytype == "friendblocked") {
var session_store = this.session_store;
/*
if (typeof recipient.friends != "undefined") {
for (var c = 0; c < recipient.friends.length; c++) {
if (recipient.friends[c].username == msg.username) {
delete recipient.friends[c];
// console.log( 'removing ' + msg.username );
}
}
}
*/
session_store.deleteFriend( recipient.username, msg.username );
}
}
// user has left the page or there is a problem with socket.io
this._disconnect = function (client, ms) {
var threshold = +new Date - ms;
session = this.session_store.get('client', client.sessionId);
if (session && session.lastAccess < threshold) {
if (session.status != 'offline') this._status(session.username, ['offline', '']);
this.session_store.remove(session.username);
}
}
};
MessageHandler.prototype.init = function (auth_handler, session_store) {
if (!this.auth_handler) {
this.auth_handler = auth_handler;
this.session_store = session_store;
}
return this;
}
MessageHandler.prototype.message = function (client, msg) {
switch (msg.type) {
case 'AUTH':
this._auth(client, msg);
break;
case 'STATUS':
this._status(msg.username, msg.status);
break;
case 'IM':
this._im(msg.from, msg.to, msg.message);
break;
case 'TYPING':
this._typing(msg.from, msg.to);
break;
case 'NOTIFICATION':
this._notification(msg.to, msg);
break;
default:
break;
}
}
MessageHandler.prototype.disconnect = function (client, SESSION_REAP_TIMEOUT) {
var msghandler = this;
setTimeout(function () {
msghandler._disconnect(client, SESSION_REAP_TIMEOUT);
}, SESSION_REAP_TIMEOUT);
}
var instance = new MessageHandler();
module.exports = function getInstance() {
return instance;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment