RabbitMQ(5)Java Client - Publish/Subscribe
We will deliver the messages to multiple consumers. This pattern is known as "publish/subscribe".
Exchanges
The Producer will not directly contact to the queues. We will have a exchange between them. And the exchange must know exactly what to do with a message it receives. Should it be appended to a particular queue? Should it be appended to many queues? Or should it get discarded. The rules for that are defined by the exchange type.
There are few exchange types available: direct, topic, headers and fanout.
channel.exchangeDeclare("logs", "fanout");
Fanout just broadcasts all the messages it receives to all the queues it knows.
We can use this command to see all the exchanges running on our server
>sudo sbin/rabbitmqctl list_exchanges
Nameless exchange
Before, we send our message using a default exchange, which we identify by the empty string("").
channel.basicPublish("", "hello", null, message.getBytes());
Temporary queues
Before we have "hello" and "task_queue". Being able to name a queue was crucial for us. Giving a queue a name is important when you want to share the queue between producers and consumers.
In the Java client, when we supply no parameters to queueDeclare() we create a non-durable, exclusive, autodelete queue with a generated name:
String queueName = channel.queueDeclare().getQueue();
Bindings
The relationship between exchange and a queue is called a binding.
channel.queueBind(queueName, "logs", "");
>sudo sbin/rabbitmqctl list_bindings
Putting it all together
Emit the message
package com.sillycat.easytalker.rabbitmq.publish;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class EmitLog {
private static final String EXCHANGE_NAME = "logs";
private final static String SERVER_HOST = "localhost";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String message = "error debugy inform warning log!";
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
Receiving the log messages
package com.sillycat.easytalker.rabbitmq.publish;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
public class ReceiveLogs {
private static final String EXCHANGE_NAME = "logs";
private final static String SERVER_HOST = "localhost";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
Queue belongs to the consumer, binding with the exchange.
references:
http://www.rabbitmq.com/tutorials/tutorial-three-java.html
We will deliver the messages to multiple consumers. This pattern is known as "publish/subscribe".
Exchanges
The Producer will not directly contact to the queues. We will have a exchange between them. And the exchange must know exactly what to do with a message it receives. Should it be appended to a particular queue? Should it be appended to many queues? Or should it get discarded. The rules for that are defined by the exchange type.
There are few exchange types available: direct, topic, headers and fanout.
channel.exchangeDeclare("logs", "fanout");
Fanout just broadcasts all the messages it receives to all the queues it knows.
We can use this command to see all the exchanges running on our server
>sudo sbin/rabbitmqctl list_exchanges
Nameless exchange
Before, we send our message using a default exchange, which we identify by the empty string("").
channel.basicPublish("", "hello", null, message.getBytes());
Temporary queues
Before we have "hello" and "task_queue". Being able to name a queue was crucial for us. Giving a queue a name is important when you want to share the queue between producers and consumers.
In the Java client, when we supply no parameters to queueDeclare() we create a non-durable, exclusive, autodelete queue with a generated name:
String queueName = channel.queueDeclare().getQueue();
Bindings
The relationship between exchange and a queue is called a binding.
channel.queueBind(queueName, "logs", "");
>sudo sbin/rabbitmqctl list_bindings
Putting it all together
Emit the message
package com.sillycat.easytalker.rabbitmq.publish;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class EmitLog {
private static final String EXCHANGE_NAME = "logs";
private final static String SERVER_HOST = "localhost";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String message = "error debugy inform warning log!";
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
Receiving the log messages
package com.sillycat.easytalker.rabbitmq.publish;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
public class ReceiveLogs {
private static final String EXCHANGE_NAME = "logs";
private final static String SERVER_HOST = "localhost";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(SERVER_HOST);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
Queue belongs to the consumer, binding with the exchange.
references:
http://www.rabbitmq.com/tutorials/tutorial-three-java.html