qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fraser Adams <fraser.ad...@blueyonder.co.uk>
Subject Re: messenger -> qpidd replyTo shenanigans.....
Date Mon, 28 Jul 2014 18:10:42 GMT
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: users-unsubscribe@qpid.apache.org
For additional commands, e-mail: users-help@qpid.apache.org


Mime
View raw message