how to set the basic message properties for message in Rabbitmq? - rabbitmq

i am using Rabbitmq Java client API.i want to set the Basic Properties for message and also get the message Id of the message.if possible please provide some code to understand the things.
Thanks

While sending a message through java client usually it is publish to a channel like
CHANNEL.basicPublish(EXCHANGE_NAME, QUEUE_ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, "message".getBytes)
Here you can set message properties
You can get the msg by using a delivery agent
You have to first bind the queue like this
Channel channel = conn.createChannel();
String exchangeName = "myExchange";
String queueName = "myQueue";
String routingKey = "testRoute";
boolean durable = true;
channel.exchangeDeclare(exchangeName, "direct", durable);
channel.queueDeclare(queueName, durable,false,false,durable, null);
channel.queueBind(queueName, exchangeName, routingKey);
boolean noAck = false;
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, noAck, consumer);
Then use delivey to get msg
QueueingConsumer.Delivery delivery;
try {
delivery = consumer.nextDelivery();
} catch (InterruptedException ie) {
continue;
}

Here is how it can be done:
int PERSISTENCE_MESSAGE = 2; // Persist message
String TEXT_MESSAGE = "text/plain";
String queueName = "QUE-1";
Channel channel = this.connection.createChannel();
channel.queueDeclare(queueName, true, false, false, null);
// Build message properties
Map messageProps = new HashMap();
//messageProps.put("TIME_MSG_RECEIVED", time);
messageProps.put("SOURCE_SYS", "SRC1");
messageProps.put("DESTINATION_SYS", "DST1");
// Set message properties
AMQP.BasicProperties.Builder basicProperties = new AMQP.BasicProperties.Builder();
basicProperties.contentType(TEXT_MESSAGE).deliveryMode(PERSISTENCE_MESSAGE)
.priority(1).headers(messageProps);
channel.basicPublish("", queueName, basicProperties.build(), message.getBytes());
System.out.println(" Sent message to RabbitMQ: '" + message + "'");
channel.close();

Related

Failed to send message using MQ

On my server side I deployed RabbitMq message middleware using docker and it works perfectly. But I combine it with asp.net core, it can't send the message successfully.
package:https://www.nuget.org/packages/RabbitMQ.Client/
I goole some answers:
RabbitMQ adopts the message response mechanism, that is, after the
consumer receives a message, it needs to send a response, and then
RabbitMQ will delete the message from the queue. If the consumer has
an exception during the consumption process, the connection is
disconnected and no response is sent. Then RabbitMQ will redeliver the
message
So I modified my code
//message received event
consumer.Received += (ch, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body);
Console.WriteLine($"Received the news: {message}");
Console.WriteLine($"received the message[{ea.DeliveryTag}] delay 10s to send receipt");
Thread.Sleep(10000);
//Confirm that the message has been consumed
channel.BasicAck(ea.DeliveryTag, false);
Console.WriteLine($"Receipt sent[{ea.DeliveryTag}]");
};
Still failed to send and no response, please help me, thank you!
I have a demo of sending a message, you may refer to it, it may be helpful.
Controller:
[Route("test")]
public void Index()
{
try
{
var factory = new ConnectionFactory();
factory.VirtualHost = "/";
factory.HostName = "localhost";
factory.Port = 5672;
factory.UserName = "guest";//Default username guest
factory.Password = "guest";//Default password guest
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "test",
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "",
routingKey: "test",
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent {0}", message);
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
catch (Exception ex)
{
Console.Write(string.Format("RabbitMQ connection error :{0}\n", ex.ToString()));
}
}
For the sake of convenience, I did not configure the connection information of rabbitmq here. I wrote it directly into the method, you can do it yourself.
Resullt:

Code to get single message from the queue in RabbitMQ using C#

How to receive single message from the queue in RabbitMQ using C#
I am using the RabbitMQ to maintain my Queue.When I am read my queue messages its shows all massage present in the queue.
I want to retrieve single message as per First come first out criteria.
Please provide me code to get the single message from the queue by using RabbitMQ
var connection = connectionFactory.CreateConnection();
var channel = connection.CreateModel();
// accept only one unack-ed message at a time
// uint prefetchSize, ushort prefetchCount, bool global
channel.BasicQos(0, 1, false);
MessageReceiver messageReceiver = new MessageReceiver(channel);
channel.BasicConsume("viewer_Queues", false, messageReceiver);
//channel.QueueDeclare("viewer_Queues", false, false, false, null);
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume("viewer_Queues", true, consumer);
BasicDeliverEventArgs ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(message + " Received.");
Console.ReadLine();
I think you need something like this, from the website Tutorials in the worker Queues Section:
`using System;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
using System.Threading;
class Worker
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using(var connection = factory.CreateConnection())
using(var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "task_queue",
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);
int dots = message.Split('.').Length - 1;
Thread.Sleep(dots * 1000);
Console.WriteLine(" [x] Done");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "task_queue",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
}`
the prefetch argument is important if you want to get only one message at a time you can read about it in the official website https://www.rabbitmq.com/

RabbitMq single Consumer with multiple queue

I want to create single consumer(Generic Listener) for multiple queues.The consumer should listen multiple queues.
Lets see in the example
channel.ExchangeDeclare(exchange: "logs", type: "fanout");
var queueName = "QeueueName.Instance1";
channel.QueueBind(queue: queueName,
exchange: "logs",
routingKey: "");
Console.WriteLine(" [*] Waiting for logs.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] {0}", message);
};
I want to associate the consumer with dynamic no of queues and they will
increase time to time so how i will associate consumer to future created queues.I have created a window service for the same so do i have to loop all the queues and associate with consumer and for the future created queues I should add them in the consumer queue list.
When I first read your question I didn't think you could bind one consumer to multiple queues, but I just tried this and it works fine:
ConnectionFactory factory = new ConnectionFactory()
{
VirtualHost = "testHost1",
UserName = "guest",
Password = "guest",
Port = 5672,
};
var connection = factory.CreateConnection();
var channel = connection.CreateModel();
channel.ExchangeDeclare("testExchange1", ExchangeType.Fanout);
channel.QueueDeclare("testQueue1");
channel.QueueDeclare("testQueue2");
channel.QueueBind("testQueue1", "testExchange1", "");
channel.QueueBind("testQueue2", "testExchange1", "");
var consumer1 = new EventingBasicConsumer(channel);
consumer1.Received += Consumer1OnReceived;
channel.BasicConsume("testQueue1", false, consumer1);
channel.BasicConsume("testQueue2", false, consumer1);
Note that your code doesn't include a call to BasicConsume(). Your consumer won't receive anything without it.

Rabbitmq - how to listen to messages on an exchange

I have a program in Java that sends messages to RabbitMQ. All I know is the exchange name. No queues, bindings, and so on.
My question is this: how can I see if the program sends these successfully, knowing only the exchange name?
Thanks.
Regards,
Serban
You can enable publisher confirmation with RabbitMQ. It's like having a send-transaction, where RabbitMQ will tell you whether or not the message was sent successfully.
Assume that we have RabbitMQ Exchange we need to create an queue to push the message to the exchange and consume it from the queue as following
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
//Declare Exchange //
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
// push message to rabbitmq exchange
channel.basicPublish(EXCHANGE_NAME, "routingkey", null, yourmessage.getBytes());
the above work as producer now we need to create queue consumer
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
//Queue Declare //
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//Queue bind //
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "routingkey");
// Queue Consume //
QueueingConsumer consumer = new QueueingConsumer(channel);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
Please look here: https://www.rabbitmq.com/tutorials/tutorial-three-java.html
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, "EXCHANGE_NAME", "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException
{
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
In a few words, you have to:
create a queue, in this case anonymous queue
bind the queue to your exchange
It is important to know what kind of the exchange you have since the binding can change, between fanout or topic or direct
In this example is fanout

How to receive messages for a correlationid from RabbitMQ using Spring AMQP

I went through the API of RabbitTemplate. It provides only receive method which gets the message from queue. However there is no way to get a message with a particular correlation id. Can you please help me understand what I am missing here.
Currently, I am using JMS API's from ActiveMQ to receive messages using the following code which createConsumer with message selector. Looking to do the same with Spring AMQP with RabbitMQ:
private ObjectMessage receiveMessage(final String readQueue, final UUID correlationId, final boolean isBroadcastMessage, final int readTimeout) throws JMSException
{
final ActiveMQConnectionFactory connectionFactory = this.findConnectionFactory(readQueue);
Connection connection = null;
Session session = null;
MessageConsumer consumer = null;
ObjectMessage responseMessage = null;
try
{
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue(readQueue);
consumer = session.createConsumer(destination, "correlationId = '" + correlationId + "'");
final Message message = consumer.receive(readTimeout);
}
finally
{
if (consumer != null)
{
consumer.close();
}
if (session != null)
{
session.close();
}
if (connection != null)
{
connection.close();
}
}
return responseMessage;
}
You are using a messageSelector string in JMS; RabbitMQ/AMQP does not have an equivalant.
Instead, each consumer gets its own queue and you use a direct or topic exchange in the broker to do the routing. I suggest you take a look at the tutorials on the rabbitmq web site and topics.
If you are using the correlationId for request/reply processing, consider using the inbuilt sendAndReceive or convertSendAndReceive methods in the template. See the reference documentation for more information.