0

This is my publisher. There are two consumers. MailConsumer and SmsConsumer.

 using(var bus = RabbitHutch.CreateBus("host=localhost").Advanced) {
            var queueName = "my.queue";
            var queueName2 = "my.queue2";
            var queue = bus.QueueDeclare(queueName);
            var queue2 = bus.QueueDeclare(queueName2);
            var channel = bus.ExchangeDeclare("MyFanout", ExchangeType.Fanout);
            bus.Bind(channel, queue, "sms");
            bus.Bind(channel, queue2, "mail");
            var input = "";
            Console.WriteLine("Enter a message. 'q' to quit.");
            while((input = Console.ReadLine()) != "q") {
                for(int i = 1; i < 2; i++) {
                    var message = new Message<TextMessage>(new TextMessage {
                        Text = input + i
                    });
                    bus.Publish(channel, "", false, false, message);
                }
            }
        }

I can subscribe with this code:

using(var bus = RabbitHutch.CreateBus("host=localhost").Advanced) {
            var queueName = "my.queue2";
            var queue = bus.QueueDeclare(queueName);

            bus.Consume(queue, x => x.Add<TextMessage>((message, info) => {
                Thread.Sleep(1000);
                Console.WriteLine("SMS: {0}", message.Body.Text);
            }));

            Console.WriteLine("Listening for messages. Hit <return> to quit.");
            Console.ReadLine();
        }

How can I achieve it via AutoSubscriber? There is no option for Queue Name in AutoSubscriber, there is "Subscription Id"

Wiebe Tijsma
  • 10,173
  • 5
  • 52
  • 68
Oguz Karadenizli
  • 3,449
  • 6
  • 38
  • 73

1 Answers1

0

There's a property on the AutoSubscriber called 'GenerateSubscriptionId', which you can set to generate the subscription id for a consumer:

subscriber.GenerateSubscriptionId = subscriptionInfo =>
{
  return "MyApplication:" + subscriptionInfo.ConcreteType.Name);
};

Then the subscription id will be used by the default conventions to generate a queue name.

Update: I think you can achieve what you want just with normal pub-sub without declaring any queue.

In your publisher you can do this:

var bus = RabbitHutch.CreateBus("host=localhost")
while((input = Console.ReadLine()) != "q") {
  for(int i = 1; i < 2; i++) {
    var message = new Message<TextMessage>(new TextMessage {
     Text = input + i
    });
    bus.Publish(message);
    }
 }

Then just create 2 consumers to subscribe to your message, and your message will be handled by both:

class SmsConsumer : IConsume<TextMessage>{
   ...
}

class LogConsumer : IConsume<TextMessage>{
   ...
}

and in your startup:

var bus = RabbitHutch.CreateBus("host=localhost")
var subscriber = new AutoSubscriber(bus,"my_applications_subscriptionId_prefix");
subscriber.Subscribe(Assembly.GetExecutingAssembly());
Console.ReadLine()

EasyNetQ will declare the exchange, queues and bindings for you. Just make sure your TextMessage class is in an assembly shared by both projects.

Wiebe Tijsma
  • 10,173
  • 5
  • 52
  • 68
  • It does not work.. From documentation: "If you call Subscribe two times with different subscription ids but the same message type, you will create two queues, each with its own consumer. A copy of each message of the given type will be routed to each queue, so each consumer will get all the messages (of that type). This is great if you've got several different services that all care about the same message type." So we don't need Fanout Exchange? Could you send a working code that includes publisher and subscriber codes? – Oguz Karadenizli Mar 23 '15 at 17:10
  • I don't get it 100%, why would you want to call it twice? To make sure the queue exists before the consumer starts? – Wiebe Tijsma Mar 23 '15 at 17:33
  • I don't want to call it twice. Think that you have the ErrorLog. And you want to send an email to the technical department and write error log to ElastichSearch Db. You create a message, publish it two separate queue via fanout and consume queues separately. This is the scenario. I've sent working example in my question. So how can I achieve it via AutoSubscribe approach? Thanks. – Oguz Karadenizli Mar 23 '15 at 18:07
  • See update. You don't need to declare the queues, you can just publish your message on the bus directly, and if the consumer was ever started, both queues will get the message. – Wiebe Tijsma Mar 23 '15 at 22:40
  • @ozz did that work for you or did I not fully understand your question? – Wiebe Tijsma Mar 26 '15 at 11:54
  • I tried it yesterday, but it did not work."my_applications_subscriptionId_prefix" is unpredictable, EasyNetq creates unique queue name.. – Oguz Karadenizli Mar 26 '15 at 14:47
  • @ozz You can override the naming conventions for (error) queues, exchanges: http://stackoverflow.com/questions/28696339/custom-error-queue-name-when-using-easynetq-for-rabbitmq/28716620#28716620 – Wiebe Tijsma Mar 27 '15 at 10:19
  • it is enough to give 3 hours for AutoSubscriber to me. I have a queue with name "myqueue" but I could not subscribe it via [ForQueue("myqueue")] – Oguz Karadenizli Mar 27 '15 at 18:48
  • There is topic based subscription and subscriptionId based subscription, and there is no working sample to achieve it. So I give up! – Oguz Karadenizli Mar 27 '15 at 18:50