EASYNETQ Subscriber Subscription message type (the. NET type of the message Class). Once a subscription to a type is set by calling the Subscribe method, a persistent queue is created on the RABBITMQ agent, and any messages of that type are placed in the queue. as soon as the connection is connected, RABBITMQ sends any message from the queue to the user.
to subscribe to a message, we need to provide EASYNETQ with the actions that are performed when the message arrives. We do this by passing a subscription delegate:
Bus. Subscribe<mymessage> ("my_subscription_id", msg = Console.WriteLine (msg). Text));
Now each time the Mymessage instance is published, EASYNETQ invokes our delegate and prints the message's Text property to the console.
The subscription ID that you pass to subscribe is important. EASYNETQ will create a unique queue for each unique combination of the message type and subscription ID on the RABBITMQ agent.
each call to subscribe will create a new queue consumer. If you call "subscribe" two times with the same message type and subscription ID, two consumers will be created with the same queue. then RABBITMQ will loop successive messages to each consumer sequentially. This is ideal for expansion and work sharing. Suppose you've created a service that handles a specific message, but it's overworked. simply launch a new instance of the service (on the same machine, or on a different machine), and you can scale it automatically without having to configure any content.
If you call "subscribe" with a different subscription ID (but with the same message type) two times, you will create two queues, each with its own consumer. a copy of each message of a given type is routed to each queue, so each consumer will get all the messages (that type of message). This is good if you have several different services that care about the same message type.
Considerations When writing a subscription callback delegate
when messages are received from a queue that is subscribed through EASYNETQ, they are placed in an in-memory queue. a single thread is in a loop, gets the message from the queue, and invokes its action proxy. because a delegate is processed one time on a single thread, long-running synchronous IO operations should be avoided. return control from Representative office as soon as possible.
using Subscribeasync
Subscribeasync allows your subscribers to delegate immediate return tasks and then perform long-running IO operations asynchronously. Once you've completed your long-term subscription, just complete the task. In the following example, we use asynchronous IO Operations (Downloadstringtask) to make a request to the Web service. When the task is complete, we write a line on the console.
Bus. Subscribeasync<mymessage> ("subscribe_async_test", message = New WebClient (). Downloadstringtask (new Uri ("http://localhost:1338/?timeout=500")) = = Console.WriteLine ("Received: ' {0} ', downloaded: ' {1} '" , message. Text, task. Result ));
Another example causes an exception to be thrown when an error occurs, and then causes the message to be placed in the default error queue:
_bus. Subscribeasync<messagetype> ("Queue_identifier", Message= Task.Factory.StartNew (() = { //Perform some actions here//If There is a exception it would result in a task complete but task faulted which//is dealt with below in the continuation}). ContinueWith (Task = { if(Task. IsCompleted &&!task. isfaulted) {//everything worked out OK } Else { //Dont catch This, it's caught further up the heirarchy and results in being sent to the default error queue //On the broker Throw NewEasynetqexception ("Message processing Exception-look in the default error queue (Broker)"); } }));
Cancel Subscription
All Subscribe methods return a Isubscriptionresult. It contains properties that describe the underlying iconsumer IExchange
and IQueue
use , you can use the advanced API to further manipulate these properties , if desired . IAdvancedBus
You can use the ISubscriptionResult
instance or its ConsumerCancellation
Property , call Dispose at any time to cancel the subscriber :
var subscriptionresult = Bus. Subscribe<mymessage> ("sub_id", MyHandler); Subscriptionresult.dispose (); // This was equivalent to SubscriptionResult.ConsumerCancellation.Dispose ();
This will prevent EASYNETQ from consuming and shutting down the consumer's channel from the queue.
Please note that processing IBus
or IAdvancedBus
The instance also cancels all the users and closes the connection to the RABBITMQ.
Don't you call subscriptionResult.Dispose()
within a message handler. This will create a race condition between the EASYNETQ confirming the message on the consumer channel subscriptionResult.Dispose()
and the call to close the channel . because of the internal architecture of the EASYNETQ, these calls are invoked on different threads and the timing is indeterminate.
"EASYNETQ Tutorial"-Subscribe