lib/client.js
function RpcClient(opts) {
    assert.object(opts, 'options');
    assert.object(opts.log, 'options.log');
    assert.number(opts.program, 'options.program');
    assert.number(opts.version, 'options.version');
    assert.string(opts.url, 'options.url');

    EventEmitter.call(this, opts);

    var self = this;

    this.conn = null;
    this.log = opts.log.child({
        component: 'RpcClient',
        serializers: require('./bunyan').serializers
    });
    this.messages = {};
    this.program = opts.program;
    this.url = mod_url.parse(opts.url);
    this.version = opts.version;

    var ID = 0;
    this._next_xid = function () {
        if (++ID === (Math.pow(2, 32) - 1))
            ID = 0;
        return (ID);
    };
    this._rpc_client = true; // MDB ::findjsobjects flag

    this.conn = net.createConnection({
        port: this.url.port,
        host: this.url.hostname
    });

    this.conn.once('error', function onErr(e) {
        self.emit('error', e);
        return;
    });

    this.conn.once('connect', function onConnect() {
        var parser = new RpcParser({
            log: self.log
        });
        parser.on('message', function onRpcMessage(msg) {
            var cfg = self.messages[msg.xid];
            var res;

            if (!cfg) {
                self.emit('error', new Error('unsolicited RPC message'), msg);
                return;
            }

            if (cfg.reply) {
                res = new cfg.reply(msg);
                msg.pipe(res);
            } else {
                res = msg;
            }

            msg.once('end', function cleanupMessageTable() {
                if (self.messages[msg.xid])
                    delete self.messages[msg.xid];
            });

            var _cb = cfg.cb;
            var _err = null;
            if (msg.reply_stat === 0) {
                switch (msg.accept_stat) {
                case 0:
                    break;

                case 1:
                    _err = new errors.RpcProgramUnavailableError();
                    break;

                case 2:
                    _err = new errors.RpcProgramMismatchError();
                    _err.mismatch_info = msg.mismatch_info;
                    break;

                case 3:
                    _err = new errors.RpcProcedureUnavailableError();
                    break;

                case 4:
                    _err = new errors.RpcGarbageArgumentsError();
                    break;

                default:
                    _err = new errors.RpcError('invalid rpc.accept_stat: ' +
                                               msg.accept_stat);
                    break;
                }
            } else if (msg.reply_stat === 1) {
                if (msg.reject_stat === 0) {
                    _err = new errors.RpcMismatchError();
                    _err.mismatch_info = msg.mismatch_info;
                } else {
                    _err = new errors.RpcAuthError();
                    _err.auth_stat = msg.auth_stat;
                }
            }

            process.nextTick(function emitRpcReply() {
                if (_err) {
                    _cb(_err, msg);
                } else {
                    _cb(null, res, msg);
                }
            });
        });
        self.conn.pipe(parser);
        self.emit('connect');
    });

    this._rpc_client = true; // MDB
}
function RpcClient(opts) {
    assert.object(opts, 'options');
    assert.object(opts.log, 'options.log');
    assert.number(opts.program, 'options.program');
    assert.number(opts.version, 'options.version');
    assert.string(opts.url, 'options.url');

    EventEmitter.call(this, opts);

    var self = this;

    this.conn = null;
    this.log = opts.log.child({
        component: 'RpcClient',
        serializers: require('./bunyan').serializers
    });
    this.messages = {};
    this.program = opts.program;
    this.url = mod_url.parse(opts.url);
    this.version = opts.version;

    var ID = 0;
    this._next_xid = function () {
        if (++ID === (Math.pow(2, 32) - 1))
            ID = 0;
        return (ID);
    };
    this._rpc_client = true; // MDB ::findjsobjects flag

    this.conn = net.createConnection({
        port: this.url.port,
        host: this.url.hostname
    });

    this.conn.once('error', function onErr(e) {
        self.emit('error', e);
        return;
    });

    this.conn.once('connect', function onConnect() {
        var parser = new RpcParser({
            log: self.log
        });
        parser.on('message', function onRpcMessage(msg) {
            var cfg = self.messages[msg.xid];
            var res;

            if (!cfg) {
                self.emit('error', new Error('unsolicited RPC message'), msg);
                return;
            }

            if (cfg.reply) {
                res = new cfg.reply(msg);
                msg.pipe(res);
            } else {
                res = msg;
            }

            msg.once('end', function cleanupMessageTable() {
                if (self.messages[msg.xid])
                    delete self.messages[msg.xid];
            });

            var _cb = cfg.cb;
            var _err = null;
            if (msg.reply_stat === 0) {
                switch (msg.accept_stat) {
                case 0:
                    break;

                case 1:
                    _err = new errors.RpcProgramUnavailableError();
                    break;

                case 2:
                    _err = new errors.RpcProgramMismatchError();
                    _err.mismatch_info = msg.mismatch_info;
                    break;

                case 3:
                    _err = new errors.RpcProcedureUnavailableError();
                    break;

                case 4:
                    _err = new errors.RpcGarbageArgumentsError();
                    break;

                default:
                    _err = new errors.RpcError('invalid rpc.accept_stat: ' +
                                               msg.accept_stat);
                    break;
                }
            } else if (msg.reply_stat === 1) {
                if (msg.reject_stat === 0) {
                    _err = new errors.RpcMismatchError();
                    _err.mismatch_info = msg.mismatch_info;
                } else {
                    _err = new errors.RpcAuthError();
                    _err.auth_stat = msg.auth_stat;
                }
            }

            process.nextTick(function emitRpcReply() {
                if (_err) {
                    _cb(_err, msg);
                } else {
                    _cb(null, res, msg);
                }
            });
        });
        self.conn.pipe(parser);
        self.emit('connect');
    });

    this._rpc_client = true; // MDB
}
/--- API