Hi Jonathan,
On 11/06/10 16:18, Jonathan Graham wrote:
> Hi Emile,
> I have two WCF services (let's call them A and B) in an existing
> application. I want to send asynchronous, one-way messages from service
> A to service B. The operation being invoked on service B can take some
> time to complete, and service A's call to B is due to an end user
> initiated operation on A. I don't want to make end users wait for B to
> complete, hence the asynchronous requirement. Service B is also a
> little fragile and is not always available, so I want any messages sent
> to it to be stored in a durable queue until B is able to process the
> messages.
I agree that a one-way (fire & forget) channel is appropriate for your
use case. Queue durability alone will not be sufficient to accomplish
your goal though, because the service host will need to reconnect to the
same queue. If you are comfortable with recompiling the ServiceModel
project in order to experiment with a possible approach, try replacing
line 171 in RabbitMQInputChannel with:
string queue = m_model.QueueDeclare(LocalAddress.Uri.AbsolutePath, true);
This will cause the service queue to have a fixed name and be durable.
The queue will then accumulate requests in the event of service B
temporarily disconnecting.
Caveats apply: This code has not been through our formal QA process. It
is meant for experimentation only and may break other things.
> [...] Unfortunately because Rabbit's WCF
> binding doesn't let us use durable queues, we haven't yet been able to
> make use of it.
This is a feature that could be added if there was sufficient demand,
but you are the first to suggest it.
> It looks like the following options are available:
>> 1. Change the way the WCF binding works so that existing queues can be
> used and/or that queues declared by the binding can be made durable. (As
> an aside, if I can find the time, I wouldn't mind contributing this
> change, but I don't have a whole lot of free time at present.)
I'm hoping that the line of code above gives you a useful place to
start. I'd be interested to know if it works for you.
> 2. No longer implement service B as a WCF service and instead use the
> RabbitMQ .NET client API to consume messages from RabbitMQ.
If you are not bound to the strictures of WCF then this can work very
simply. There are many examples in the RabbitMQ.Client.Examples that
illustrate how to send messages from a message producer to a consumer.
You will need to do some of the work that RabbitMQ ServiceModel does for
you, such as declaring and binding a queue and structuring the message
in the way that the consumer can understand it.
Regards
Emile