消息发布端发送消息的方法
channel.basicPublish(exchangeName,routingKey,true,null, msg.getBytes());
void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;
void basicPublish(String exchange, String routingKey, boolean mandatory, BasicProperties props, byte[] body) throws IOException;
void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body) throws IOException;
exchange:交换器名称,指定消息需要发送到哪个交换器中。如果设置为空字符串,则消息会被发送到RabbitMQ默认的交换器中。
routingKey:路由键,交换器根据路由键将消息存储到相应的队列之中。
mandatory:交换器无法根据自身类型和路由键找到一个符合条件的队列时的处理方式
true:RabbitMQ会调用Basic.Return命令将消息返回给生产者
false:RabbitMQ会把消息直接丢弃
immediate:设置true时,如果该消息关联的队列上有消费者,则立即投递,否则这条消息不存入队列;如果与路由键匹配的所有队列都没有消费者时,该消息会通过Basic.Return返回至生产者
props:消息属性集,包含14个属性成员,如持久化、优先级、投递模式、过期时间等等
body:消息体,需要发送的消息
消息接收端发送消息的方法
channel.exchangeDeclare(exchangeName,"topic",true,false, null);
/**
* Declare an exchange.
* @see com.rabbitmq.client.AMQP.Exchange.Declare
* @see com.rabbitmq.client.AMQP.Exchange.DeclareOk
* @param exchange the name of the exchange
* @param type the exchange type
* @param durable true if we are declaring a durable exchange (the exchange will survive a server restart)
* @param autoDelete true if the server should delete the exchange when it is no longer in use
* @param arguments other properties (construction arguments) for the exchange
* @return a declaration-confirm method to indicate the exchange was successfully declared
* @throws java.io.IOException if an error is encountered
*/
Exchange.DeclareOk exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete,
Map<String, Object> arguments) throws IOException;
channel.queueDeclare(queueName,true,false,false,null);
/**
* Declare a queue
* @see com.rabbitmq.client.AMQP.Queue.Declare
* @see com.rabbitmq.client.AMQP.Queue.DeclareOk
* @param queue the name of the queue
* @param durable true if we are declaring a durable queue (the queue will survive a server restart)
* @param exclusive true if we are declaring an exclusive queue (restricted to this connection)
* @param autoDelete true if we are declaring an autodelete queue (server will delete it when no longer in use)
* @param arguments other properties (construction arguments) for the queue
* @return a declaration-confirm method to indicate the queue was successfully declared
* @throws java.io.IOException if an error is encountered
*/
Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map<String, Object> arguments) throws IOException;
channel.queueBind(queueName,exchangeName,routingKey);
/**
* Bind a queue to an exchange, with no extra arguments.
* @see com.rabbitmq.client.AMQP.Queue.Bind
* @see com.rabbitmq.client.AMQP.Queue.BindOk
* @param queue the name of the queue
* @param exchange the name of the exchange
* @param routingKey the routing key to use for the binding
* @return a binding-confirm method if the binding was successfully created
* @throws java.io.IOException if an error is encountered
*/
Queue.BindOk queueBind(String queue, String exchange, String routingKey) throws IOException;
channel.basicConsume(QUEUE_NAME, true, consumer);
/**
* Start a non-nolocal, non-exclusive consumer, with
* a server-generated consumerTag.
* @param queue the name of the queue
* @param autoAck true if the server should consider messages
* acknowledged once delivered; false if the server should expect
* explicit acknowledgements
* @param callback an interface to the consumer object
* @return the consumerTag generated by the server
* @throws java.io.IOException if an error is encountered
* @see com.rabbitmq.client.AMQP.Basic.Consume
* @see com.rabbitmq.client.AMQP.Basic.ConsumeOk
* @see #basicConsume(String, boolean, String, boolean, boolean, Map, Consumer)
*/
String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;
重点来了!!!
简易版自定义 Consumer
只需要重写DefaultConsumer 的handleDelivery方法即可取出消息,额外 属性新增属性等操作。
DefaultConsumer 源码 如下 :
/**
* Convenience class providing a default implementation of {@link Consumer}.
* We anticipate that most Consumer implementations will subclass this class.
*/
public class DefaultConsumer implements Consumer {
/** Channel that this consumer is associated with. */
private final Channel _channel;
/** Consumer tag for this consumer. */
private volatile String _consumerTag;
/**
* Constructs a new instance and records its association to the passed-in channel.
* @param channel the channel to which this consumer is attached
*/
public DefaultConsumer(Channel channel) {
_channel = channel;
}
/**
* Stores the most recently passed-in consumerTag - semantically, there should be only one.
* @see Consumer#handleConsumeOk
*/
@Override
public void handleConsumeOk(String consumerTag) {
this._consumerTag = consumerTag;
}
/**
* No-op implementation of {@link Consumer#handleCancelOk}.
* @param consumerTag the defined consumer tag (client- or server-generated)
*/
@Override
public void handleCancelOk(String consumerTag) {
// no work to do
}
/**
* No-op implementation of {@link Consumer#handleCancel(String)}
* @param consumerTag the defined consumer tag (client- or server-generated)
*/
@Override
public void handleCancel(String consumerTag) throws IOException {
// no work to do
}
/**
* No-op implementation of {@link Consumer#handleShutdownSignal}.
*/
@Override
public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {
// no work to do
}
/**
* No-op implementation of {@link Consumer#handleRecoverOk}.
*/
@Override
public void handleRecoverOk(String consumerTag) {
// no work to do
}
/**
* No-op implementation of {@link Consumer#handleDelivery}.
*/
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body)
throws IOException
{
// no work to do
}
/**
* Retrieve the channel.
* @return the channel this consumer is attached to.
*/
public Channel getChannel() {
return _channel;
}
/**
* Retrieve the consumer tag.
* @return the most recently notified consumer tag.
*/
public String getConsumerTag() {
return _consumerTag;
}
}
具体代码
import com.rabbitmq.client.*;
import java.io.IOException;
public class Recv {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception{
//创建一个连接
ConnectionFactory factory = new ConnectionFactory();
factory.setPort(5672);
factory.setVirtualHost("/");
//连接本地,如果需要指定到服务,需在这里指定IP
factory.setHost("122.51.242.170");
Connection connection = factory.newConnection();
//创建一个通道
Channel channel = connection.createChannel();
//申明接收消息的队列,与发送消息队列"hello"对应
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" 消息队列创建成功,等待消息传入 ");
//The extra DefaultConsumer is a class implementing the Consumer interface
//we'll use to buffer the messages pushed to us by the server.
Consumer consumer = new DefaultConsumer(channel){
//重写DefaultConsumer中handleDelivery方法,在方法中获取消息
@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(QUEUE_NAME, true, consumer);
}
}
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/*
public class Producer{
public static void main(String[] args) throws IOException, TimeoutException {
// 创建一个 ConnectFactory
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("122.51.242.170");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
// 通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
// 通过Connection 创建一个Channel
Channel channel = connection.createChannel();
// 通过channel 发送数据
for (int i = 0; i < 5 ; i++)
{
String msg = "Hello RabbtiMQ";
channel.basicPublish("", "test001", null, msg.getBytes());
}
// 关闭相关的连接
channel.close();
connection.close();
}*/
public class Producer {
/*
* 定义一个队列“hello”
*/
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws IOException, TimeoutException {
//创建一个连接
ConnectionFactory factory = new ConnectionFactory();
//连接本地,如果需要指定到服务,需在这里指定IP
factory.setHost("122.51.242.170");
Connection connection = factory.newConnection();
//创建一个通道
Channel channel = connection.createChannel();
//申明通道发送消息的队列,把消息发送至消息队列‘hello’
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
//Declaring a queue is idempotent - 如果队列不存在则会创建一个队列
//消息内容为byte array, so可以自己随意编码
for(int i =0 ;i < 5; i++){
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
}
System.out.println(" [x] Sent '" + message + "'");
//消息发送完成后,关闭通道和连接
channel.close();
connection.close();
}
}