On 28/07/14 12:56, Gordon Sim wrote:
On 07/26/2014 04:05 PM, Fraser Adams wrote:
As normal for QMF I want a dynamic reply address/queue, which I can get
if I do.

var subscription = messenger.subscribe('amqp://0.0.0.0:5673/#');

However I don't know how to find the name of the queue thus created at
run time that I can use to populate the replyTo?

my subscribe returns the subscription but my subscription.getAddress();
just returns an empty string - it could be an issue with my
implementation

I suspect this is indeed the issue. The pn_subscription_address call will call pni_messenger_work until it either gets an error or the subscription has a non-null address (the name of the dynamic node being returned by the broker in the attach it sends). It returns NULL if an error is encountered.



Hi Gordon,
Thanks for the post, it turns out that I actually got things working, it wasn't *actually* an issue with my implementation so much as me not really understanding how subscription was working, coupled with the fact that I have to work in an entirely asynchronous manner being that it's JavaScript :-)

What I ended up doing was:

subscription = messenger.subscribe('amqp://0.0.0.0:5673/#');

then in my pumpData function (which gets registered using messenger.on('work', pumpData); and in turn gets called by some library internal code that uses WebSocket event handlers and interacts with pn_messenger_work) I do:

var pumpData = function() {
    if (!subscribed) {
        var subscriptionAddress = subscription.getAddress();
        if (subscriptionAddress) {
            subscribed = true;
            onSubscription(subscriptionAddress);
        }
    }

    while (messenger.incoming()) {
// The second parameter forces Binary payloads to be decoded as strings // this is useful because the broker QMF Agent encodes strings as AMQP // binary, which is a right pain from an interoperability perspective.
        var t = messenger.get(message, true);
        onMessage();
        messenger.accept(t);
    }

    if (messenger.isStopped()) {
        message.free();
        messenger.free();
    }
};

So pumpData gets called when there is any work to do in this case it's checking for a non-empty subscription address and when that happens it calls onSubscription and sets a flag to stop that being called multiple times.

As everything is async and non-blocking pn_subscription_address won't block so I end up needing to check it on my "work" handler. It makes sense when you thing about it, but async code takes a while to get your head around.

As it happens the quirks of async code was one of the reasons that I decided to create this little application, though once I got the basics working I got inspired so I'm now writing a pure JavaScript node.js async implementation of qpid-config :-)

So I can basically now demo QMF working with Messenger and all of the async request/response/correlationID stuff.

I've got queueListRecurse and exchangeListRecurse working fine now output copied below with a headers exchange binding thrown in because it's me :-)

node qmf.js
queueListRecurse
Queue '14aa23b1-4437-4533-ac8c-0cdb2e265020_receiver-xxx'
    bind [14aa23b1-4437-4533-ac8c-0cdb2e265020_receiver-xxx] => ''
Queue 'TempQueue773cafc4-2f23-465a-b190-c6dca6d53f38'
    bind [TempQueue773cafc4-2f23-465a-b190-c6dca6d53f38] => ''
bind [admin.c41b4183-1af5-43fe-9e09-6dc257475b39] => qmf.default.direct {'x-filter-jms-selector': ''}
Queue 'TempQueuea420d79d-754b-4c92-b7bf-b27d4bee47a8'
    bind [TempQueuea420d79d-754b-4c92-b7bf-b27d4bee47a8] => ''
    bind [agent.ind.#] => qmf.default.topic {'x-filter-jms-selector': ''}
Queue 'TempQueuee0dab982-7135-4eb5-884a-2c1c282a34c7'
    bind [TempQueuee0dab982-7135-4eb5-884a-2c1c282a34c7] => ''
bind [admin.c41b4183-1af5-43fe-9e09-6dc257475b39.async] => qmf.default.direct {'x-filter-jms-selector': ''}
Queue 'test'
    bind [test] => ''
bind [mykey] => amq.match {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'x-match': 'all'}

My JavaScript port of Messenger/Codec/Message etc. is to all intents and purposes complete, I'm just working on some examples now and tidying a few things up.

Oh yeah, while I remember (and you'll see my moaning in one of the comments above) I'd forgotten how much I get frustrated when C/C++ applications end up sending "strings" as AMQP binary types, which is pretty much the standard case in QMF. I ended up deserialising those into a Binary type which (to avoid unnecessary copying) has the data backed by the underlying data owned by the Message :-) now because I wait for the queue, exchange and binding to return before I do anything with the messages that was giving me quirky results. As in the comments above because sending strings as binary seems to be a bit of a common thing I ended up adding a flag to my messenger.get() implementation to allow the user to specify that AMQP binary gets deserialised into a native JavaScript string. When I got that little quirk sorted the QMF code winds up being nice and simple - just manipulation of JavaScript Arrays and Objects.

I *really* like JavaScript :-)

Frase


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to