GithubHelp home page GithubHelp logo

bramqp's People

Contributors

bakkerthehacker avatar jbrick avatar numminorihsf avatar toddgjohnson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bramqp's Issues

Adding headers to message

The message is not published when I add headers. Callback is triggered (which prints "Published message") but the message is not routed to the queue. Am I doing something wrong?

var message = [
    'UserUpdate',
    {
        'id': pbx_user_id,
        'pbx_profile_id': new_pbx_schedule_id,
        'pbx_profile_type': 'schedule'
    }
];

msg = JSON.stringify( message );

var table = {
    'headers': {
        'company': {
            type: 'Unsigned 64-bit',
            data: 4
        }
    }
};

app.amqpHandle.content( 1, 'basic', table, msg, function() {
        console.log( 'Published message' );
} );

removeListener

Considering that the 'handle' is an instance of Socket, which is a instance of events.EventEmitter, shouldn't the removeListener work within the library?

I am trying to remove some listeners after a time (handle.on(event)). Is it possible to do in any other way?

Channel-scoped handlers

Hello, I've been trying out this lib and liking it a lot so far - keeping to the low level stuff seems to be avoiding many of the problems node-amqp has with it's high/low mix.

There does seem to be a bit of an issue however, in both some internal code and documentation.

The incoming method events are fired on the handle object, and pass the channel as their first argument - however none of the examples or code actually check that this channel param actually matches the expected one!

While the examples could be updated to always have if (channel != 1) return;, I think this is a common enough use-case that it would make sense to provide some sugar for this.

Perhaps one of these?

handle.channelOn(1, 'close', fn);
handle.channel(1).on('close');

// In both cases the idea would just be to desugar into:
handle.on('close', function(ch) {
  if (ch != expected) return;
  handler.apply(this, arguments);
});

Update Readme

need to add

  • AMQP exception
  • adding new specifications
  • method event

Add input validator

The frame parser and serializer were designed to work only on valid data. The user data should be validated. Some of the validation requirements for method arguments may need to be read from the spec.

AMQP error code 0?

looking into error handling, I was looking at possibly using the error handle.emit event to also emit the AMQP errors instead of having to:

// handle any AMQP errors that cause the connection to close
            handle.on('connection.close', function(reply_code, reply_text, class_id, method_id){
                console.log("error code connection");
                console.log(reply_code);
            });
            // handle any AMQP errors that cause the channel to close
            handle.on('channel.close', function(reply_code, reply_text, class_id, method_id){
                console.log("error code channel");
                console.log(reply_code);
            });

I was writing some test code for this and I got an error code of 0 when I tried to open a queue on channel 2. Now channel 2 isn't open, but I thought I would get
channel-error 504. Furthermore I can't find documentation of this error code 0

here is code to reproduce

var bramqp = require('bramqp');
var net = require('net');
var async = require('async');


bramqp.selectSpecification('rabbitmq/full/amqp0-9-1.stripped.extended', function(error) {
        if (error) {
            console.log("spec error");
            throw error;
        }
        var socket = net.connect({
            port : 5672
        }, function() {
            bramqp.initializeSocket(socket, function(error, handle) {
            if (error){
                console.log("socket init error");
                throw error;
            }
            handle.on("error", function(error){
                console.log("handle Error");
                throw error;
            });
            // handle any AMQP errors that cause the connection to close
            handle.on('connection.close', function(reply_code, reply_text, class_id, method_id){
                console.log("error code connection");
                console.log(reply_code);
                console.log(reply_text);
            });
            // handle any AMQP errors that cause the channel to close
            handle.on('channel.close', function(reply_code, reply_text, class_id, method_id){
                console.log("error code channel");
                console.log(reply_code);
            });
            async.series([ function(seriesCallback) {
                handle.openAMQPCommunication('guest', 'guest', true, seriesCallback);
            }, function(seriesCallback){
                handle.queue.declare(2, null, false, true, true, true, false, {});
                handle.once('queue.declare-ok', function(channel, method, data) {
                    console.log('queue declared');
                    seriesCallback();
                });
            }]);
        });
    });
});

and the output
error code connection
0
{ chassis: 
   [ { name: 'client', implement: 'MUST' },
     { name: 'server', implement: 'MUST' } ],
  response: [ { name: 'close-ok' } ],
  field: 
   [ { name: 'reply-code', domain: 'reply-code' },
     { name: 'reply-text', domain: 'reply-text' },
     { name: 'class-id', domain: 'class-id' },
     { name: 'method-id', domain: 'method-id' } ],
  name: 'close',
  synchronous: '1',
  index: '50' }

Multi channel selecting queue for worker prioritization

I am having a hard time figuring out how to implement multi-channels and have specific queues listening on specific channels. All the examples in the tutorials seem to be single channel.

The idea is to have a task system where there are priorities. Workers need to work on tasks with high priorities and go to lower priority tasks as the other queues empty out.

For the discussion let's say we have 3 priorities: 1 - really important, 2 - medium importance, 3 - low importance.

Each worker can do up to 5 things at once.

So, I'm thinking about doing this via 3 queues and then have 3 channels each consume from 1 queue setting the channel qos to 5. This should throttle things across cluster workers, although not optimally since I may end up with 15 messages at the worker at any time.

Any examples on how to do that? (or maybe some other way of accomplishing the same thing)

Thanks,

Alberto

Can not choose virtual host

May be add a "vhost" parameter to the openAMQPCommunication function and pass it to the AMQP connection.open function.

no error thrown on invalid credentials passed to openAMQPCommunication

hi :)

If the rmsOpts.username contains an unknown to RabbitMQ name nothing happens. I would expect an error to be thrown.

    handle.openAMQPCommunication(
      rmsOpts.username,
      rmsOpts.password,
      rmsOpts.heartbeat,
      rmsOpts.vhost,
      (error, results) => {
        if (error) {
          fail(error);
        } else {
          ok(handle);
        }
      },
    );

the question: is there a proper way of handling bramqp errors?

PS: the flow terminates abruptly in connectionHandle.js on line 208.

Format for arguments

After some debugging I found that the format for arguments (eg. for handle.queue.declare) is

{'x-message-ttl': { type: 'Signed 32-bit', data: 30000 } }

I couldn't find this in the documentation, and it may save others some time if this were included.

basic.consume seems to lock the rest of the module code

Hi.

This is just an architecture question. Suppose I do publishing and consuming messages from the same node.js module. As soon as I start basic.consume the whole application seems to wait for it to complete.

Should this be, say, mono, I would have put the basic.consume in a separate thread. But what approach should I take in node.js?

Thank you.

Correct way to publish persistent message in durable queue

Following the example no.2 (work queues) I understand is declaring a durable queue:

handle.queue.declare(1, 'task_queue', false, true, false, false, false, {});
                handle.once('queue.declare-ok', function(channel, method, data) {
                    console.log('queue declared');
                    seriesCallback();
                });

And publishing persistent messages with:

handle.basic.publish(1, '', 'task_queue', false, false, function() {
                    handle.content(1, 'basic', {
                        delivery_mode : 2
                    }, message, seriesCallback);
                });

But looking in the web-ide of rabbitmq the persistent messages counter inside the queue stays in 0. When I manually publish the message thorught the webide works weell and the counter changes..
Im missing something? How can I publish true a pesistent message with your library?? Thanks so much, I really like the library

Add optional content to basic.publish to prevent multiplexing issues

basic.publish must be followed by content without any other messages inbetween. The current implementation fails to provide a software lock bewteen these two. Other messages can fall between due to multiplexing on the event loop.

The original implementation should remain to retain the ability to multiplex between channels. The new implementation should take the content with the message and perform one write on the entire frame set.

channel.close never happens

Hi.

After opening a channel I cannot close it. Please, have a look at the code, and the console output below.

Thank you!

THE CODE

require("babel-polyfill");

const series = require('async').series;
const nextTick = require('async').nextTick;

class Infra {

  constructor(connection, settings) {
    this.connection = connection;
    this.settings = settings;
    this.handle = this.connection.handle;
    this.channel_num = 2;
  };

  * channel_number() {
    yield this.channel_num++;
  };

  open_channel() {
    return new Promise((resolve, reject) => {
      const cn = this.channel_number().next().value;
      this.handle.channel.open(cn);

      this.handle.once(`${cn}:channel.close`, () => {
        console.log(`channel.close: ${cn}`);

        this.handle.channel['close-ok'](cn, () => {
          console.log(`[${cn}]close-ok:`);
        });

      });

      this.handle.once(`${cn}:channel.flow`, (channel, method, data) => {
        console.log(`${cn}:channel.flow:`, channel, method, data);
        this.handle.channel['flow-ok'](cn, data.active, () => {
          console.log(`[${cn}]flow-ok:`, data);
        });
      });

      this.handle.once(`${cn}:channel.open-ok`, () => {
        console.log(`${cn}:channel.open-ok`);
        resolve(cn);
      });

    });
  };

  * object_names(className) {
    for(let object_name of this.settings[className]) {
      yield object_name;
    };
  };

  declare_exchange(channel_number, object_config) {
    return new Promise((resolve, reject) => {
      const nowait = false;

      this.handle.exchange.declare(
        channel_number,
        object_config.name,
        object_config.exchange_type,
        object_config.passive,
        object_config.durable,
        object_config.auto_delete,
        object_config.internal,
        nowait,
        object_config.arguments,
        (error) => {
          if(error) {
            console.error(error);
            reject(error);
          };
        }
      );
      this.handle.on(
        `${channel_number}:exchange.declare-ok`, (channel, method, data) => {
          console.log(`${channel_number}:exchange.declare-ok: ${object_config.name}`);
          resolve();
        }
      );
    });
  };

  create_exchanges() {
    return new Promise((resolve, reject) => {
      const obj_names_gen = this.object_names('exchanges');

      for(let next_name of obj_names_gen) {
        const object_config = this.settings[next_name];

        this.open_channel()
          .then((channel_number) => {

            this.declare_exchange(channel_number, object_config)
              .then(() => {
                console.log(`BEFORE: this.handle.channel.close(${channel_number})`);
                this.handle.channel.close(channel_number, 200, 'object declared OK');
              })
              .catch((error) => {
                reject(error);
              });

          })
          .catch((error) => {
            reject(error);
          });
      };
    });
  };

  create_queues() {
    return new Promise((resolve, reject) => {
      resolve();
    });
  };

  create_bindings() {
    return new Promise((resolve, reject) => {
      resolve();
    });
  };

  create() {

    return new Promise((resolve, reject) => {

      series([

        (callback) => {
          this.create_exchanges()
            .then(() => {
              nextTick(callback);
            })
            .catch((error) => {
              callback(error);
            });
        },

        (callback) => {
          this.create_queues()
            .then(() => {
              nextTick(callback);
            })
            .catch((error) => {
              callback(error);
            });
        },

        (callback) => {
          this.create_bindings()
            .then(() => {
              nextTick(callback);
            })
            .catch((error) => {
              callback(error);
            });
        },

      ], (error, result) => {
        if(error) {
          console.error(error);
          reject(error);
        }
        resolve();
      });

    });
  };

};

module.exports = Infra;

THE CONSOLE OUTPUT

2:channel.open-ok
3:channel.open-ok
4:channel.open-ok
5:channel.open-ok
6:channel.open-ok
3:exchange.declare-ok: x-dlx
7:channel.open-ok
2:exchange.declare-ok: x-ae
4:exchange.declare-ok: x-fci
5:exchange.declare-ok: x-rci
BEFORE: this.handle.channel.close(3)
BEFORE: this.handle.channel.close(2)
BEFORE: this.handle.channel.close(4)
BEFORE: this.handle.channel.close(5)
6:exchange.declare-ok: x-idx
7:exchange.declare-ok: x-cmd
BEFORE: this.handle.channel.close(6)
BEFORE: this.handle.channel.close(7)

State machine can be broken by exceptions

I'm not 100% on whether this is a problem, or how best to fix it.

The two options I can think of are making the callback in parseFrameEnd use nextTick, or calling resetFrameState before that callback is fired. The second option here probably leaves you needing to handle continuing to read the buffer in the case where there are unread bytes - although you could just trust that more bytes will be along later and will consume parsing.

Anyway here's the code to trigger the error:

'use strict';

var bramqp = require('./');
var net = require('net');
var async = require('async');

process.on('uncaughtException', function(ex) {
    if (ex.message == 'handleable application error') {
        console.warn("Got an app error, but it's ok!");
        return;
    }
    console.warn("Error: %s", ex.stack);
});

var socket = net.connect({
    port : 5672
});
bramqp.initialize(socket, 'rabbitmq/full/amqp0-9-1.stripped.extended', function(error, handle) {

    handle.openAMQPCommunication('guest', 'guest', true, onConnected);

    function onConnected(err) {
        if (err) throw (err);

        handle.queue.declare(1, 'hello');
        handle.once('queue.declare-ok', function(channel, method, data) {
            handle.queue.declare(1, 'world');

            throw new Error('handleable application error');
        });
    }
});

Multiple publishes not going through

Hi,

I am using the library on node to create some jobs to external machines. I am using version 0.3.2.

The problem I am having is, whenever, at the same request, I do multiple publishes using the same handle, they fail. This is how I am doing this:

var bramqp = require('bramqp')
  , net = require('net')
  , async = require('async')

module.exports = new function () {
  var handle
    , socket = net.connect(socketConfig)

  function openConnection() {
    bramqp.initialize(socket, 'rabbitmq/full/amqp0-9-1.stripped.extended', function(err, _handle) {
      handle = _handle

      async.series([function(seriesCallback) {
        handle.openAMQPCommunication('user', 'pass', true, host, seriesCallback);
      }, function(seriesCallback) {
        handle.on('queue.declare-ok', queueReady);
        handle.queue.declare(1, 'q1', false, true, false, false, false, {})
        handle.queue.declare(1, 'q2', false, true, false, false, false, {})
      }],
      function (err) {})
    })
  }

  openConnection()

  this.send = function (message, queue) {
    handle.basic.publish(1, '', queue, true, true, function() {
      handle.content(1, 'basic', {
        'content-type' : 'application/json',
        'delivery-mode' : 2
      }, JSON.stringify(message), function (err) {
      });
    });
  }
}

I have tried to implement the basic return method to see if there is anything wrong with rabbit, but I wasn't able to see anything, and I don't think I did it correctly.

As I tried to explain, within the request I can call the send only one time, and it does publish correctly. Consecutive calls fails silently. Other calls to my API do work, and the first send works too.

Do you have any idea on what I am doing wrong here?

"content" handler cannot be channel scoped

I'm unsure whether this is a problem in practice as the content always follows delivery, which is scoped. Is this guaranteed on the socket?

It does lead to a slightly inconsistent API, where I can subscribe to "1:basic.deliver", but then have to follow it up with a plain "content" handler.

Clarify table type syntax in documentation / examples

Actually all methods that take arbitrary properties require them to be of "table" type. Example is content properties.headers

This means you can't pass in a plain js object, but actually have to type the values, e.g. turn it to a key value map where the value is {type: "$oneOfValueTypes", data: "$theValue"}

I guess putting it in one of the examples would help people understand (I thought this is not obvious)

Cheers,
Arne

Add Tests

Currently there are no tests. I did test most of the code while writing it, but there still may be issues, especially in the FrameParser and FrameSerializer.

Incorrect number of method arguments in tutorial 3 consumer.js

I was using the 3rd tutorial (3 Publish Subscribe) as a starting point to do a basic connection and consume test on a remote broker. I copied the code from consumer.js into my node app and adjusted the socket values, username, password, and vhost to connect to my remote host. The connection worked, but when I would publish a message, nothing was being received in node via the console from line 40 on in consumer.js.

I noticed on a stackoverflow post similar example code but I noticed on the equivalent to line 36 in consumer.js:

handle.basic.consume(1, queueName, false, true, true, false, {});

...had an extra argument after queueName, a 'null' value. Once I figured out these methods were being declared by the specification XML document, I poked into the specification declared on line 12, 'rabbitmq/full/amqp0-9-1.stripped.extended'.

It declares 8 fields, not 7 like in line 36 listed above. As soon as I added an 8th argument, a 'null' right after the queueName field, I was able to start consuming published messages ok.

Basically, this example doesn't work as-is in my testing, I think it's the wrong number of arguments on line 36 for the declared specification file. This was really confusing to track down as my first experience trying to use the library.

What worked for me was:

handle.basic.consume(1, queueName, null, false, true, true, false, {});

Thanks!

Passing null queue to handle.queue.declare() fails assertions

Problem

Calling queue.declare() with null as the value of the queue parameter causes bramqp to fail the assertion tests. The specification says "The queue name MAY be empty". And (apparently) this used to work in bramqp as the the RPC example (rpc_client.js) has this line:

self.handle.queue.declare(1, null, false, false, true, false, false, {});

Which throws the following error:

TypeError: Cannot read property 'length' of null
    at Object.length (C:\XXX\node_modules\bramqp\lib\assertion.js:6:16)
    at module.exports.checkAssertion (C:\XXX\node_modules\bramqp\lib\assertion.js:31:39)
    at FrameSerializer.serializeFields (C:\XXX\node_modules\bramqp\lib\frameSerializer.js:275:4)
    at FrameSerializer.serializeFrameMethod (C:\XXX\node_modules\bramqp\lib\frameSerializer.js:305:7)
    at ConnectionHandle.methodBuffer (C:\XXX\node_modules\bramqp\lib\connectionHandle.js:333:23)
    at ConnectionHandle.method (C:\XXX\node_modules\bramqp\lib\connectionHandle.js:299:25)
    at Object.declare (C:\XXX\node_modules\bramqp\lib\connectionHandle.js:91:12)

Solution

Replacing null with an empty string passes the assertion.

self.handle.queue.declare(1, '', false, false, true, false, false, {});

Conclusion

I think the assertion should accept null or undefined as a valid empty value. Or, at least, the examples should be updated.

Error in "tutorial/1 Hello World"

.../node_modules/bramqp/lib/frameParser.js:436
throw parseError;
^
TypeError: Object # has no method 'serializeLong'
at Object.FrameSerializer.serializeLongString as Long string
at FrameSerializer.serializeValue (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/frameSerializer.js:279:34)
at FrameSerializer.serializeTable (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/frameSerializer.js:269:9)
at FrameSerializer.serializeLongString (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/frameSerializer.js:228:8)
at FrameSerializer.serializeFields (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/frameSerializer.js:293:34)
at FrameSerializer.serializeFrameMethod (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/frameSerializer.js:325:7)
at ConnectionHandle.method (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/connectionHandle.js:241:23)
at Object.start-ok (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/connectionHandle.js:95:11)
at ConnectionHandle. (/Users/vvolle/workspaces/me/nodejs/code/sample/node_modules/bramqp/lib/connectionHandle.js:142:33)
at ConnectionHandle.g (events.js:175:14)

Unable to publish

Hi,

I'm running into an issue when publishing with the library.

I consume a queue [on channel 1], process messages, and publish results back to the same RMQ cluster [on channel 2]. I have thousands of messages per second, and publish isn't working (actually the content callback is called, but no message is really published).

_handle.basic.publish(2, exchange, routingKey, false, false, function (publishError) {
  if (publishError) {
    console.log(publishError);
    return f(publishError);
  }

  console.log("content for message " + message.generic.id);
  _handle.content(2, 'basic', {
    'content-type': 'application/json'
  }, JSON.stringify(message), function () {
    console.log('message published: ' + message.generic.id);
  });
});

I wanted to know if it could be relative to the following statement :
"The basic.publish has an issue where it must be followed by content without any other messages on that channel inbetween. I will be updating the API to fix this."

Because before "content for message" is printed, I have several calls to _handle.basic.publish on channel 2

Error when bind operation cannot complete

Hello,
I tried various ways, but I cannot figure out how to get an exception/error when a bind operation cannot complete (e.g., when the queue or exchange name does not correspond to an existing queue/exchange on the rabbitmq server).
If I add a callback after the parameters for the queue.bind, I am called no matter if the bind performs ok or not, and I get no error.

Is there a way to do this ?

Thanks

pg

Socket Error running Tutorial 1

Running the example code for Tutorial 1 shows the following output

  • node.js 0.10.22
  • bramqp 0.1.2
  • async 0.2.9
queue declared
channel closed
connection closed
all done
Socket error:
{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }

[DEP0005] DeprecationWarning: Buffer() is deprecated

Hi. With Node v10.1.0:

$ NODE_OPTIONS='--throw-deprecation' npm test

> [email protected] test /Users/dexter/src/js/bramqp
> vows --spec


  ♢ concurrent connections

events.js:167
      throw er; // Unhandled 'error' event
      ^

DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
    at showFlaggedDeprecation (buffer.js:159:11)
    at new Buffer (buffer.js:174:3)
    at FrameParser.resetFrameState (/Users/dexter/src/js/bramqp/lib/frameParser.js:285:26)
    at new FrameParser (/Users/dexter/src/js/bramqp/lib/frameParser.js:25:7)
    at /Users/dexter/src/js/bramqp/lib/connectionHandle.js:17:22
    at /Users/dexter/src/js/bramqp/lib/specification.js:57:5
    at Parser.<anonymous> (/Users/dexter/src/js/bramqp/node_modules/xml2js/lib/parser.js:303:18)
    at Parser.emit (events.js:182:13)
    at Parser.options.Emitter.emit (/Users/dexter/src/js/bramqp/node_modules/vows/lib/vows.js:241:24)
    at SAXParser.onclosetag (/Users/dexter/src/js/bramqp/node_modules/xml2js/lib/parser.js:261:26)
Emitted 'error' event at:
    at Parser.exports.Parser.Parser.parseString (/Users/dexter/src/js/bramqp/node_modules/xml2js/lib/parser.js:326:16)
    at Parser.parseString (/Users/dexter/src/js/bramqp/node_modules/xml2js/lib/parser.js:5:59)
    at /Users/dexter/src/js/bramqp/lib/specification.js:43:17
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:422:3)
npm ERR! Test failed.  See above for more details.

I have a problem of connection TLS "error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:1293:SSL alert number 40"

Hello,
I need help :(

this is my code :

'use strict';
var bramqp = require('bramqp');
var tls = require('tls');
var fs = require('fs');
var socket = tls.connect({
host : 'Hostname',
port : port,
key : fs.readFileSync('cert/cert.pem'),
ca : [ fs.readFileSync('cert/cacert.pem') ],
passphrase :'passephrase',
secureProtocol :'TLSv1_method'

});

Result :
vents.js:72
throw er; // Unhandled 'error' event
^
Error: 3074393856:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:1293:SSL alert number 40

at SlabBuffer.use (tls.js:235:18)
at CleartextStream.read [as _read] (tls.js:455:29)
at CleartextStream.Readable.read (_stream_readable.js:341:10)
at EncryptedStream.write [as _write] (tls.js:369:25)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at EncryptedStream.Writable.write (_stream_writable.js:183:11)
at write (_stream_readable.js:602:24)
at flow (_stream_readable.js:611:7)
at Socket.pipeOnReadable (_stream_readable.js:643:5)

Note : I tried to connect in Php with the same configurations(certif, port, hostname ...) and I managed to connect

Thank you for your help

Request for channel.open example

Hi!

I would like to ask you to give an example of the channel.open function.

I have the following workflow of re-creating the RMQ infrastructure:

  1. according to JSON description create a bunch of exchanges,
  2. according to JSON description create a bunch of queues,
  3. according to JSON description create bindings among the exchanges and queues

In Python I would establish a separate channel to create each single binding. Now I am curious how to properly create a new channel on the handler.

Invalid Date

I've error (Invalid Date) with timestamp field from RabbitMQ. It looks like here should be a division instead multiplication (at least for me it helps).

openAMQPCommunication doesn't call the callback when VHOST doesn't exist

When a certain VHOST does not exist, the openAMQPCommunication should call the callback with the error as response. Right now it never actually calls the callback.

If the VHOST is set up correctly, the callback is executed.

I added the following to my code:

this.socket.on('data', (data) => {
        console.log('\n' + data.toString());
});

And I notice the following output:

NOT_ALLOWED - access to vhost '/random' refused for user 'guest'

errno: 'ECONNRESET', when handle is shared between two javascript classes

Hi.

I have run into trouble sharing a handle between two javascript objects. Is it at all possible to share it?

What I have:

  1. a BramQP javascript object which is reponsible for socket initialization, bramqp.selectSpecification(), and bramqp.initializeSocket(). When all is done the object passes back the handle to the caller;
  2. the caller object instantiates two other javascript objects RmqGUID and RmqUA that are responsible for queue declaration and message passing to these queues.

Note: I have copy-pasted most of the code from bramqp documentation, except for disconnect function call.

What is the problem: when only a single object uses the handle it all runs OK. But, as soon as there are two objects sharing the same handle the ECONNRESET happens.

I guess, I just do not understand something very basic about the bramqp. Please, help me dig it.

Examples Based on RabbitMQ Tutorials

Kudos for an interesting, no-frills approach to an AMQP library.

I think it would be helpful to me and others if you published examples of using your library to implement RabbitMQ's classic tutorials. This seems to be done by many AMQP libs and provides a helpful way to see what the code looks like in real scenarios, and to even try it out!

Issue passing parameters to content

below code is from rabbit mq tutorial 6 converted to bramqp

var bramqp = require('bramqp');
var net = require('net');
var async = require('async');

function Rpc_client(callback){
    var self = this;
    bramqp.selectSpecification('rabbitmq/full/amqp0-9-1.stripped.extended', function(error) {
        if (error) {
            console.log(error);
        }
        var socket = net.connect({
            port : 5672
        }, function() {
            self.socket = socket;
            bramqp.initializeSocket(socket, function(error, handle) {
            self.handle = handle;
            async.series([ function(seriesCallback) {
                self.handle.openAMQPCommunication('guest', 'guest', true, seriesCallback);
            }, function(seriesCallback){
                self.handle.queue.declare(1, null, false, true, true, true, false, {});
                self.handle.once('queue.declare-ok', function(channel, method, data) {
                    console.log('queue declared');
                    self.callbackQueueName = data.queue;
                    seriesCallback();
                });
            }, function(seriesCallback){            
                handle.basic.consume(1, self.callbackQueueName, null, false, true, false, false, {});
                handle.once('basic.consume-ok', function(channel, method, data) {
                    console.log('consuming from queue');
                    console.log(data);
                    seriesCallback();
                });
            }, function(seriesCallback){
                handle.on('basic.deliver', function(channel, method, data) {
                    console.log('incoming message');
                    console.log(data);
                });
                console.log("a");
                seriesCallback();
            }, function(seriesCallback){
                handle.once('content', function(channel, className, properties, content) {
                    console.log('got a message:');
                    console.log(content.toString());
                    console.log('with properties:');
                    console.log(properties);
                    if (self.correlation_id == properties.correlation_id){
                        self.response = content;
                    }
                });
                console.log("b");
                seriesCallback();
            }, function(error){
                if (error){
                    console.log(error);
                }
                callback();
            }]);
        });
    });
}); 
}


Rpc_client.prototype.call = function(n, callback){
    var self = this;
    self.response = null;
    require('crypto').randomBytes(1, function(ex, buf) {
        self.correlation_id = buf.toString('hex');
        self.handle.basic.publish(1, '', 'rpc_queue', false, false, function() {
            var properties = {
                    'reply-to' : "a",
                    'correlation-id' :"a"
            };
            self.handle.content(1, 'basic', properties, n, function(contentError){
                if (contentError){
                    console.log(contentError);          
                }
                while (self.response == null){              
                }
                callback(self.response);
            });         
        });
    });
};

fibonacci_rpc = new Rpc_client(function(){
    console.log(" [x] Requesting fib(30)");
    fibonacci_rpc.call("30", function(response){
        console.log(response);
    });
});

Problem with server messages

There is a problem with rabbitmq:
Then server start block new messages, client emits TypeError.
To reproduce this:

shell: rabbitmqctl set_vm_memory_high_watermark 0

node.js code:

var bramqp = require('bramqp');
var net = require('net');

var socket = net.connect({
  port : 5672
});

bramqp.initialize(socket, 'rabbitmq/full/amqp0-9-1.stripped.extended', function(error, handle) {
  handle.openAMQPCommunication('guest', 'guest', true, function(seriesCallback) {
    handle.basic.publish(1, '', 'hello', false, false, function() {
      handle.content(1, 'basic', {}, 'Hello World!', function(){});
    });
  });
});

stack trace:

eventsevents.js:154
      throw er; // Unhandled 'error' event
      ^

TypeError: Cannot read property 'field' of undefined
    at FrameParser.parseFrameMethod (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/frameParser.js:268:49)
    at FrameParser.parseFrameEnd (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/frameParser.js:413:63)
    at FrameParser.parseFramePayload (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/frameParser.js:390:16)
    at FrameParser.parseFrameStart (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/frameParser.js:372:16)
    at FrameParser.parse (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/frameParser.js:431:57)
    at Socket.<anonymous> (/home/numminorihsf/Projects/iojs/rabbit/node_modules/bramqp/lib/connectionHandle.js:45:22)
    at emitOne (events.js:90:13)
    at Socket.emit (events.js:182:7)
    at readableAddChunk (_stream_readable.js:147:16)
    at Socket.Readable.push (_stream_readable.js:111:10).js:154

The reason is that in spec there are no methods ("blocked", "undlocked") with ids (60, 61). So there is an error with it.
Please, update spec for rabbitmq.
https://www.rabbitmq.com/resources/specs/amqp0-9-1.extended.xml

Add support for RabbitMQ client capabilities

RabbitMQ server supports numerous extensions to AMQP. In order for some of the extensions to function the client must specify one or more capabilities while establishing the connection.

The capabilities field is supplied inside the client-properties parameter to the connection.start-ok method.

Recommend that a capabilities parameter be added to openAMQPCommunication() with a default value consistent with that of the RabbitMQ Java Client (and as shown in the capabilities link above).

The added positive side effect is that the standard AMQP client connection info can be supplied inside the client-properties parameter as well, as described in the spec:

Client properties.
The properties SHOULD contain at least these fields: "product", giving the name of the 
client product, "version", giving the name of the client version, "platform", giving the 
name of the operating system, "copyright", if appropriate, and "information", giving 
other general information.

This allows bramqp to be identified by the admin functions of the server, for example:

rabbitmq admin - connections page

openAMQPCommunication() prone to failures (silent hanging)

Most easily reproduced when starting multiple concurrent connections to a local rabbitmq server: Only a subset (usually one) connection will succeed, all others get "stuck" waiting for the 'connection.tune' event, which, has already passed before the listener is established. (Local instance of rabbitmq is specified because otherwise network latency may contributing to hiding the issue.)

Discovered after upgrading bramqp from 0.1.17 to current master branch. The calling application starts a pool of concurrent workers each binding to a single queue for load sharing.

Tested on OS X 10.9.5 with node v0.10.24 and Debian Wheezy with node 0.10.33.

Buffer error connecting to ActiveMQ docker container

Buffer error connecting to ActiveMQ docker container

Hi folks - I'm getting an error when connecting to a vanilla ActiveMQ docker container. It looks like an issue in bramqp

Original issue raised in AMQPea

Example used

Your Hello World example, which works fine on RabbitMQ, but fails on ActiveMQ:

Docker command for my container:

  • Assume docker running on 192.168.123.123 in OracleBox.
  • docker run --name data-activemq -p 1883:1883 -p 5672:5672 -p 8161:8161 -p 61613:61613 -p 61614:61614 -p 61616:61616 -e 'ACTIVEMQ_MIN_MEMORY=512' -e 'ACTIVEMQ_MAX_MEMORY=2048' -v $DATA_PATH/activemq:/data/activemq -h data-activemq -d webcenter/activemq:5.12.0

Sender example

With connection modified to

var socket = net.connect({
    host : "192.168.69.100",
    port : 9672
});

I get this error

$ node ActiveMQ-bramqp-send.js
events.js:85
      throw er; // Unhandled 'error' event
            ^
RangeError: Attempt to allocate Buffer larger than maximum size: 0x3fffffff bytes
    at new Buffer (buffer.js:71:11)
    at FrameParser.parseFrameStart (C:\git\queue-demos\node_modules\bramqp\lib\frameParser.js:367:29)
    at FrameParser.parse (C:\git\queue-demos\node_modules\bramqp\lib\frameParser.js:433:57)
    at Socket.<anonymous> (C:\git\queue-demos\node_modules\bramqp\lib\connectionHandle.js:54:22)
    at Socket.g (events.js:199:16)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:538:20)

Receiver example

As above

Please help!

How to create a singleton for bramqp?

Hello! I'm new to this library and just want to ask if it is possible to reuse the initialize anywhere in the nodejs code?

I understand that when setting up bramqp the minimum is this

var bramqp = require('bramqp');
var net = require('net');

var socket = net.connect({
  port: 5672
})

bramqp.initialize(socket, 'rabbitmq/full/amqp0-9-1.stripped.extended', function(initError, handle) {
    if (initError) {
        console.log(initError);
    }
});

My goal is to reuse the instance of bramqp and just use handle to allow me execute handle.basic.consume anywhere.

Thanks for the help!

Breaking changes introduced by assertions from the specification

The assertions from the specification in this commit dbf94bd introduced breaking changes. In our case we were using whitespaces in the queue names as our Rabbitmq server doesn't validate it and this assertion is failing:
https://github.com/bakkerthehacker/bramqp/blob/master/specification/rabbitmq/full/amqp0-9-1.stripped.extended.xml#L87
I understand that strictly following the specification is the right way but any workaround without change the queue names would be very helpful.

Cannot read property 'call' of undefined

Hi.

If the arguments is not empty (see JSON config below), the exchange.declare would return the "Cannot read property 'call' of undefined". If the arguments contains nothing then exchange.declare succeeds.

Please, advise.

{
  "name":         "x-ae",
  "description":  "Alternative Exchange",
  "type":         "direct",
  "passive":      false,
  "durable":      true,
  "auto_delete":  false,
  "internal":     false,
  "no_wait":      false,
  "arguments":    {
    "x-dead-letter-exchange":   "x-dl"
  }
}

This is the trace:

at FrameSerializer.serializeValue (backend/node_modules/bramqp/lib/frameSerializer.js:284:35)
      at FrameSerializer.serializeTable (backend/node_modules/bramqp/lib/frameSerializer.js:273:9)
      at FrameSerializer.serializeFields (backend/node_modules/bramqp/lib/frameSerializer.js:304:34)
      at FrameSerializer.serializeFrameMethod (backend/node_modules/bramqp/lib/frameSerializer.js:336:7)
      at ConnectionHandle.methodBuffer (backend/node_modules/bramqp/lib/connectionHandle.js:378:23)
      at ConnectionHandle.method (backend/node_modules/bramqp/lib/connectionHandle.js:347:25)
      at Object.declare (backend/node_modules/bramqp/lib/connectionHandle.js:121:12)
      at RMQInfra._mapper (rmqinfra.js:65:40)
      at Array.map (native)
      at RMQInfra._recreate_exchanges (rmqinfra.js:92:41)
      at RMQInfra.recreate (rmqinfra.js:111:14)
      at Object.on_initialized (rmqinfra_spec.js:32:27)
      at RMQConnector.<anonymous> (rmqconnector.js:32:41)
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:697:13
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:52:16
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:272:32
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:44:16
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:694:17
      at backend/node_modules/bramqp/node_modules/async/lib/async.js:173:37
      at ConnectionHandle.<anonymous> (backend/node_modules/bramqp/lib/connectionHandle.js:315:6)
      at FrameParser.<anonymous> (backend/node_modules/bramqp/lib/connectionHandle.js:141:8)
      at FrameParser.parseFrameMethod (backend/node_modules/bramqp/lib/frameParser.js:273:7)
      at FrameParser.parseFrameEnd (backend/node_modules/bramqp/lib/frameParser.js:415:63)
      at FrameParser.parseFramePayload (backend/node_modules/bramqp/lib/frameParser.js:392:16)
      at FrameParser.parseFrameStart (backend/node_modules/bramqp/lib/frameParser.js:374:16)
      at FrameParser.parse (backend/node_modules/bramqp/lib/frameParser.js:433:57)
      at Socket.<anonymous> (backend/node_modules/bramqp/lib/connectionHandle.js:40:22)
      at readableAddChunk (_stream_readable.js:146:16)
      at Socket.Readable.push (_stream_readable.js:110:10)
      at TCP.onread (net.js:523:20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.