Skip to content

Instantly share code, notes, and snippets.

@FLYBYME
Created October 3, 2011 00:54
Show Gist options
  • Select an option

  • Save FLYBYME/1258209 to your computer and use it in GitHub Desktop.

Select an option

Save FLYBYME/1258209 to your computer and use it in GitHub Desktop.
var rpc = module.exports = function() {
events.EventEmitter.call(this);
var self = this;
this.counter = 0;
this.functions = {};
this.promises = {};
this.id
this.slaves = {}
this.expose('list', function() {
var list = [];
// console.log('list')
for(var key in self.functions) {
this.set(key, 'typeof: ' + typeof (self.functions[key]));
}
this.send();
})
this.expose('init', function(authKey) {
this.send('init', true);
self.emit('init')
})
this.expose('slave', {
'new' : function(master, slave) {
Logger('New Slave: ' + slave + ' from master: ' + master)
this.send('status', 'OK!');
//self.emit('new.slave', master, slave)
}
})
return this;
};
// So will act like an event emitter
util.inherits(rpc, events.EventEmitter);
rpc.prototype._runCallBack = function(data) {
var promises = this.promises;
process.nextTick(function() {
promises[data.id].callBack.apply({}, [data.error, data.result]);
delete promises[data.id];
});
}
//
rpc.prototype._runError = function(code, id, method, callBack) {
var result;
switch (code) {
case 32700:
result = ( {
'result' : null,
'error' : {
'message' : 'Parse error',
'code' : code
},
'id' : id
})
break;
case 32600:
result = ( {
'result' : null,
'error' : {
'message' : 'Invalid Request',
'code' : code
},
'id' : id
})
break;
case 32601:
result = ( {
'result' : null,
'error' : {
'message' : 'Method not found.',
'code' : code
},
'id' : id
})
break;
case 32602:
result = ( {
'result' : null,
'error' : {
'message' : 'Invalid params.',
'code' : code
},
'id' : id
})
break;
case 32603:
result = ( {
'result' : null,
'error' : {
'message' : 'Internal error.',
'code' : code
},
'id' : id
})
break;
case 32000:
default:
result = ( {
'result' : null,
'error' : {
'message' : 'Server error.',
'code' : 32000
},
'id' : id
})
}
Logger('RPC ERROR CODE: ' + result['error']['code'] + ' MSG: ' + result['error']['message'] + ' METHOD: ' + method, 5)
return true;
}
//
rpc.prototype._runExpose = function(data, socket, serverid, callBack) {
var exsosed = new Exposed(data, socket, rpc, serverid, callBack);
var method = this.functions[data.method];
var params = data.params;
Logger('RPC call from socket: ' + socket.id + ' with method: ' + data['method'])
this.counter++;
process.nextTick(function() {
method.apply(exsosed, data.params);
});
}
// *************************************//
rpc.prototype.request = function(data, socket, serverid, callBack) {
// console.log(data)
if((data.hasOwnProperty('result') || data.hasOwnProperty('error') ) && data.hasOwnProperty('id') && this.promises.hasOwnProperty(data.id)) {
return this._runCallBack(data)
}
if(!data.hasOwnProperty('id')) {
return this._runError(32600, null, data.method, callBack);
}
if(!(data.hasOwnProperty('method') && typeof (data.method) === 'string')) {
return this._runError(32600, data.id, data.method, callBack);
}
if(!data.hasOwnProperty('params') && Array.isArray(data.params)) {
return this._runError(32602, data.id, data.method, callBack);
}
if(!this.functions.hasOwnProperty(data.method)) {
return this._runError(32601, data.id, data.method, callBack);
}
this._runExpose(data, socket, serverid, callBack)
};
//
rpc.prototype.expose = function(mod, object) {
if( typeof (object) === 'object') {
var funcs = [];
for(var funcName in object) {
var funcObj = object[funcName];
if( typeof (funcObj) == 'function') {
this.functions[mod + '.' + funcName] = funcObj;
funcs.push(funcName);
}
}
} else if( typeof (object) == 'function') {
this.functions[mod] = object;
}
return this;
};
//
rpc.prototype.call = function(method, params, socket, callBack) {
var id = keyGen()
this.promises[id] = {
method : method,
params : params,
callBack : callBack
}
socket.write({
method : method,
params : params,
id : id
})
}
rpc.prototype.callSocket = function(method, params, socketId, callBack) {
var id = keyGen()
this.promises[id] = {
method : method,
params : params,
callBack : callBack
}
var socket = this.slaves[socketId]
if(socket) {
socket.write({
method : method,
params : params,
id : id
})
}
}
//
rpc.prototype.socket = function(socket) {
var self = this;
self.slaves[socket.id] = socket
socket.on('data', function(data) {
self.request(data, socket, socket.id, function(err, result) {
socket.write({
result : result,
error : err,
id : data.id
})
})
})
};
rpc.prototype.io = function(socket) {
var self = this;
socket._write = function(data) {
socket.emit('rpc', data);
}
self.slaves[socket.id] = socket
socket.on('rpc', function(data) {
self.request(data, socket, socket.id)
})
};
//
rpc.prototype.broadCast = function(method, params, callBack) {
var slaves = this.slaves;
for(var key in slaves) {
this.call(method, params, slaves[key], callBack)
}
};
//
rpc.prototype.server = function(server) {
var self = this
var idserver = this.id = keyGen()
server.on('connection', function(socket) {
socket.setEncoding('utf8')
socket = new Socket({
socket : socket
})
self.socket(socket)
socket.on('close', function() {
delete self.slaves[socket.id]
})
self.call('init', [], socket, function(err, result) {
console.log(arguments)
self.emit('slave.new', idserver, socket.id)
self.broadCast('slave.new', [idserver, socket.id], function(err, result) {
console.log(result)
})
})
}).on('request', function(request, response) {
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment