Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// clientside
- var RPC = (function (rpc) {
- var counter = 0;
- var channels = {};
- var deferreds = {};
- var baseURL;
- var rpcMaster;
- var loadChannel = function (name) {
- rpcMaster.emit('load channel', name);
- channels[name]._loadDef = channels[name]._loadDef || Q.defer();
- channels[name]._socket = io.connect(baseURL + '/rpc-' + name)
- .on('return', function (data) {
- deferreds[data.toId].resolve(data.value);
- })
- .on('error', function (data) {
- deferreds[data.toId].reject(data.reason);
- });
- };
- rpc.connect = function (url) {
- baseURL = url;
- rpcMaster = io.connect(url + '/rpc-master');
- rpcMaster.__channelListLoad = Q.defer();
- rpcMaster
- .on('channels', function (data) {
- var name = data.list.pop();
- while(name) {
- channels[name] = {};
- loadChannel(name);
- name = data.list.pop();
- }
- rpcMaster.__channelListLoad.resolve(channels);
- })
- .on('channelFns', function (data) {
- var channelObj = channels[data.name];
- data.fnNames.forEach(function (fnName) {
- channelObj[fnName] = function () {
- counter++;
- channelObj._socket.emit('invocation',
- {Id: counter, fnName: fnName, argsArray: Array.prototype.slice.call(arguments, 0)}
- );
- deferreds[counter] = Q.defer();
- return deferreds[counter].promise;
- }
- });
- channelObj._loadDef.resolve(channelObj);
- })
- };
- rpc.allChannelsLoaded = function (func) {
- var promises = [];
- for(var name in channels){
- var channel = channels[name];
- promises.push(channel._loadDef.promise)
- }
- Q.all(promises).then(function () {
- func();
- })
- };
- rpc.onChannelLoaded = function (name, callback) {
- rpcMaster.__channelListLoad.promise.then(function (channels) {
- channels[name]._loadDef = channels[name]._loadDef || Q.defer();
- channels[name]._loadDef.promise.then(function (channelObj) {
- callback(channelObj);
- });
- })
- };
- return rpc;
- }(RPC || {}));
- /// serverside
- var io;
- var channels = {};
- var getChannelNames = function () {
- var names = [];
- for(var channel in channels){
- names.push(channel);
- }
- return names;
- };
- var getFnNames = function (channelName) {
- var names = [];
- for(var channel in channels[channelName]){
- names.push(channel);
- }
- return names;
- };
- module.exports = {
- createMaster: function createMaster(ioP) {
- io = ioP;
- var rpcMaster = io
- .of('/rpc-master')
- .on('connection', function (socket) {
- socket.emit('channels', { list: getChannelNames() });
- socket.on('load channel', function (name) {
- if (channels.hasOwnProperty(name)) {
- socket.emit('channelFns', {name: name, fnNames: getFnNames(name)})
- }
- })
- });
- },
- expose: function (channel, toExpose) {
- ioChannel = io
- .of('/rpc-'+channel)
- .on('connection', function (socket) {
- socket.on('invocation', function (data) {
- if (toExpose.hasOwnProperty(data.fnName) && typeof toExpose[data.fnName] === 'function') {
- var that = toExpose['this'] || toExpose;
- var retVal = toExpose[data.fnName].apply(that, data.argsArray);
- if (typeof retVal.then === 'function') { // this is async function, so we will emit 'return' after it finishes
- //promise must be returned in order to be treated as async
- retVal.then(function (asyncRetVal) {
- socket.emit('return', { toId: data.Id, value: asyncRetVal });
- }, function (error) {
- socket.emit('error', { toId: data.Id, reason: error });
- });
- } else {
- socket.emit('return', { toId: data.Id, value: retVal });
- }
- } else {
- socket.emit('error', {toId: data.Id, reason: 'no such function has been exposed: ' + data.fnName });
- }
- });
- });
- // channels[channel] = ioChannel;
- channels[channel] = toExpose;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement