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]