/** * Helper for `onSlackMessage`, sends an incoming message from Slack to a group * in separate request context. * @private */ function dispatchToGroup(msg, callback) { RQ.getGlobal('persget').push('slackMsg.getGroup', pers.get.bind(null, msg.tsid), function cb(err, group) { if (err) callback(err); group.getRQ().push('slackMsg.dispatch', group.chat_send_msg.bind(group, msg, callback)); } ); }
Session.prototype.enqueueMessage = function enqueueMessage(msg) { log.trace({data: msg}, 'queueing %s request', msg.type); metrics.increment('net.amf.rx', 0.01); if (msg.type === 'ping') { this.processRequest(msg); } else { var rq = this.pc ? this.pc.getRQ() : RQ.getGlobal('prelogin'); rq.push(msg.type, this.processRequest.bind(this, msg), this.handleAmfReqError.bind(this, msg), {session: this, obj: this.pc, timerTag: msg.type}); } };
/** * Server-side RPC request handler. Executes a function on an object * specified by TSID (within a separate request context) and returns * the result to the remote caller. * * @param {string} callerId ID of the component requesting the function * call (for logging) * @param {object} obj the object on which a function should be called * @param {string|null} tag ID tag of ongoing request process this RPC belongs * to (if any) * @param {string} fname name of the function to call on the object * @param {array} args function call arguments * @param {function} callback * ``` * callback(error, result) * ``` * callback for the RPC library, returning the result (or errors) to * the remote caller */ function handleRequest(callerId, obj, tag, fname, args, callback) { metrics.increment('net.rpc.rx'); if (!obj || !_.isFunction(obj[fname])) { var msg = util.format('no such function: %s.%s', obj, fname); return callback(new RpcError(msg)); } orProxy.proxify(args); // unmarshal arguments var logtag = util.format('%s.%s.%s', callerId, obj.tsid ? obj.tsid : obj, fname); log.debug('%s(%s)', logtag, _.isArray(args) ? args.join(', ') : args); var rpcReq = function rpcReq() { var ret = obj[fname].apply(obj, args); // convert <undefined> result to <null> so RPC lib produces a valid // response (it just omits the <result> property otherwise) if (ret === undefined) ret = null; return ret; }; var rpcCallback = function rpcCallback(err, res) { if (err) { log.error(err, 'exception in %s', logtag); } if (!_.isFunction(callback)) { log.error('%s called without a valid callback', logtag); } else { log.trace('%s finished', logtag); res = orProxy.refify(res); // marshal return value return callback(err, res); } }; try { var rq = RQ.getGlobal('rpc'); if (obj.tsid && isLocal(obj) && _.isFunction(obj.getRQ)) { rq = obj.getRQ(); } rq.push(tag, rpcReq, rpcCallback, {waitPers: true}); } catch (err) { return rpcCallback(err); } }
/** * Wrapper around {@link module:data/rpc~handleRequest|handleRequest} * for game object function calls. * * @param {string} callerId ID of the calling component (for logging) * @param {string} tsid TSID of the game object to call the function on * @param {string|null} tag ID tag of ongoing request process this RPC belongs * to (if any) * @param {string} fname name of the function to call on the object * @param {array} args function call arguments * @param {function} callback callback for the RPC library, returning * the result (or errors) to the remote caller */ function objectRequest(callerId, tsid, tag, fname, args, callback) { // backwards compatibility with external components if (!_.isString(fname)) { args = fname; fname = tag; tag = util.format('%s.%s.%s', callerId, tsid, fname); } RQ.getGlobal('persget').push('rpc.get.' + tsid, pers.get.bind(null, tsid), function cb(err, obj) { if (!err && !obj) err = new Error('object not found: ' + tsid); if (err) { log.error(err, 'error loading %s for RPC', tsid); return callback(err); } if (obj.__isRP && config.isGsid(callerId)) { var msg = 'RPC for object not handled by this GS: ' + tsid; log.error(msg); return callback(new Error(msg)); } handleRequest(callerId, obj, tag, fname, args, callback); } ); }
GameObject.prototype.getRQ = function getRQ() { return RQ.getGlobal(); };
Player.prototype.getRQ = function getRQ() { if (this.location && rpc.isLocal(this.location)) { return RQ.get(this.location); } return RQ.getGlobal(); };