1

First of all, I know there is already an answer to a similar question here, but I am still not sure this is because of RabbitMQ's impossibility or because I haven't researched enough.

I come from JS/Node background where event pub/sub pattern works like this: when many consumers subscribe to the same topic with pub/sub pattern, all of them should get the same message whenever some producer publishes it.

I expect to implement the same pattern with a message broker.


For example:

Consumer 1 listens to 'request.user.#'

Consumer 2 listens to 'request.user.#'

Consumer 3 listens to 'request.#.#'

Producer 1 publishes to topic 'request.user.add'

Producer 2 publishes to topic 'request.user.detail'


What RabbitMQ actually does (according to this RabbitMQ example about Topics)

Consumer 3 gets both messages, while either Consumer 1 or Consumer 2 gets the first message, and only either of them gets the second message.


What I expect to implement

Three of them gets both messages.


Do you have any idea to implement this with a message broker (RabbitMQ in top priority)? Please point out if I miss something or am not clear somewhere in my question.

Thanks in advance.


EDIT with SOLUTION:

Thanks to @cantSleepNow, here is the code (NodeJS) for Consumer 1 and Consumer 2 that I have come up with after his hint:

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', (err, conn) => {
  conn.createChannel((err, ch) => {
    var ex = 'topic_exchange'; // Exchange name    
    ch.assertExchange(ex, 'topic'); // Exchange with 'topic' type    
    ch.assertQueue('', {exclusive: true}, (err, q) => {
      ch.bindQueue(q.queue, ex, 'request.user.#'); // Topic pattern
      ch.consume(q.queue, (msg) => {
        // Process message
      });
    });
  });
});
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
hirikarate
  • 3,055
  • 4
  • 21
  • 27

2 Answers2

1

Well this is possible using the fanout method. You can use RabbitMQ as a broadcast mechanism.

This will have one Sender and multiple subscribers and the link is here and you can find it under the Tutorial three: Publish/Subscribe senction

mapmalith
  • 1,303
  • 21
  • 38
0

What I expect to implement
Three of them gets both messages.

Well simply use the topic exchange and have each consumer declare it's own queue with appropriate routing key.

When you're publishing, you are publishing to a topic exchange (let's call it E1) with (for example) 'request.user.add' and all the queues bound to E1 with the matching routing keys(since we are talking topics here) will get the message.

Or maybe to put it like this: one message is consumed from one queue once, and from one exchange as many times as there are queues bound to it (with appropriate routing keys).

EDIT after @hirikarate added the solution to question

Well, I don't use javascript, but I'll try to help :) With exclusive you're saying that only one consumer can connect to the queue, which is ok. Also if you create a queue with a unique name in each consumer you'd achieve almost the same (obviously the difference is that other consumers would be allowed to consume from it) Again, don't know in JS, but there should be a way that you create a queue with the given name, or have the server return the name to you. Other then that looks ok, you just need to test it.

Community
  • 1
  • 1
cantSleepNow
  • 9,691
  • 5
  • 31
  • 42
  • I editted my question with the solution I came up with, please have a look and give me feedback. – hirikarate Feb 17 '17 at 11:15
  • @hirikarate Ok, I have added a bit to the answer since it was too long for comment. – cantSleepNow Feb 17 '17 at 11:22
  • Calling assertQueue with emptry string as first param will tell RabbitMQ to create a queue and choose a unique name for it. According to this link https://www.rabbitmq.com/tutorials/tutorial-three-javascript.html (Temporary queues). I didn't let two consumers bind to same queue because only one of them gets the message from queue. Btw, I got your idea and will mark this as final answer. I will do more testing. – hirikarate Feb 17 '17 at 11:32