Spring与Rabbit AMQP集成,用于“客户端发送消息 - >服务器接收&返回返回队列中的消息 - >客户端获取相关消息”

时间:2014-05-05 09:49:00

标签: rabbitmq spring-amqp

我能够使用Rabbit Java API编写一个java程序,并执行以下操作:

  1. 客户端通过Rabbit MQ交换/队列发送带有相关ID的消息(说UUID - " 348a07f5-8342-45ed-b40b-d44bfd9c4dde")。

  2. 服务器收到消息。

  3. 服务器通过具有相同关联ID的Rabbit MQ交换/队列发送响应消息 - " 348a07f5-8342-45ed-b40b-d44bfd9c4dde"。

  4. 客户端仅在与1相同的主题中收到相关消息。

  5. 下面是使用Rabbit API的Send.java和Recv.java。我需要帮助来转换此示例以使用Spring AMQP集成,特别是在第4步接收部分。我正在寻找类似于可以使用相关ID过滤消息的接收方法。

    Send.java:

    import java.util.UUID;
    
    import com.rabbitmq.client.AMQP.BasicProperties;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.ConnectionFactory;
    import com.rabbitmq.client.QueueingConsumer;
    
    public class Send {
    
        private final static String REQUEST_QUEUE = "REQUEST.QUEUE";
        private final static String RESPONSE_QUEUE = "RESPONSE.QUEUE";
    
        public static void main(String[] argv) throws Exception {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
    
            channel.queueDeclare(REQUEST_QUEUE, false, false, false, null);
            String message = "Hello World!";
            String cslTransactionId = UUID.randomUUID().toString();
            BasicProperties properties = (new BasicProperties.Builder())
                .correlationId(cslTransactionId)
                .replyTo(RESPONSE_QUEUE).build();
    
            channel.basicPublish("", REQUEST_QUEUE, properties, message.getBytes());
    
            System.out.println("Client Sent '" + message + "'");
    
    
            Channel responseChannel = connection.createChannel();
            responseChannel.queueDeclare(RESPONSE_QUEUE, false, false, false, null);
    
            QueueingConsumer consumer = new QueueingConsumer(channel);
            responseChannel.basicConsume(RESPONSE_QUEUE, false, consumer);
            String correlationId = null;
            while (true) {
                QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                String responseMessage = new String(delivery.getBody());
                correlationId = delivery.getProperties().getCorrelationId();
                System.out.println("Correlation Id:" + correlationId);
                if (correlationId.equals(cslTransactionId)) {
                        System.out.println("Client Received '" + responseMessage + "'");
                    responseChannel.basicAck(delivery.getEnvelope().getDeliveryTag(), true);
                    break;
                }
            }
    
            channel.close();
            connection.close();
        }
    }
    

    Recv.java

    import com.rabbitmq.client.ConnectionFactory;
    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.Channel;
    import com.rabbitmq.client.QueueingConsumer;
    import com.rabbitmq.client.AMQP.BasicProperties;
    
    public class Recv {
    
        private final static String REQUEST_QUEUE = "REQUEST.QUEUE";
        private final static String RESPONSE_QUEUE = "RESPONSE.QUEUE";
    
        public static void main(String[] argv) throws Exception {
    
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
    
            channel.queueDeclare(REQUEST_QUEUE, false, false, false, null);
            System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
    
            QueueingConsumer consumer = new QueueingConsumer(channel);
            channel.basicConsume(REQUEST_QUEUE, true, consumer);
            String correlationId = null;
            while (true) {
                QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                String message = new String(delivery.getBody());
                correlationId = delivery.getProperties().getCorrelationId();
                System.out.println("Correlation Id:" + correlationId);
                System.out.println("Server Received '" + message + "'");
                if (correlationId != null)
                    break;
                }
    
                String responseMsg = "Response Message";
                Channel responseChannel = connection.createChannel();
                responseChannel.queueDeclare(RESPONSE_QUEUE, false, false, false, null);
                BasicProperties properties = (new BasicProperties.Builder())
                .correlationId(correlationId).build();
    
                channel.basicPublish("", RESPONSE_QUEUE, properties,responseMsg.getBytes());
    
                System.out.println("Server Sent '" + responseMsg + "'");
    
                channel.close();
                connection.close();
           }
    }
    

    运行gary提供的Java配置后,我试图将配置移动到XML格式,以便服务器端添加监听器。以下是XML配置:

    的server.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration"
        xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
        xmlns:rabbit="http://www.springframework.org/schema/rabbit"
        xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
        xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
            http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
            http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
            http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.3.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean 
            id="serviceListenerContainer"
            class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
                <property name="connectionFactory" ref="connectionFactory" />
                <property name="queues" ref="requestQueue"/>
                <property name="messageListener" ref="messageListenerAdaptor"/>
        </bean>
    
        <bean id="messageListenerAdaptor"
            class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter">
            <property name="delegate" ref="pojoListener" />
        </bean>
    
        <bean 
            id="pojoListener"
            class="PojoListener"/>
    
        <bean
            id="replyListenerContainer"
            class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
            <property name="connectionFactory" ref="connectionFactory"/>
            <property name="queues" ref="replyQueue"/>
            <property name="messageListener" ref="fixedReplyQRabbitTemplate"/>
        </bean>
    
        <!-- Infrastructure -->
        <rabbit:connection-factory 
            id="connectionFactory" 
            host="localhost" 
            username="guest" 
            password="guest" 
            cache-mode="CHANNEL" 
            channel-cache-size="5"/>
    
        <rabbit:template 
            id="fixedReplyQRabbitTemplate" 
            connection-factory="connectionFactory"
            exchange="fdms.exchange"
            routing-key="response.key"
            reply-queue="RESPONSE.QUEUE">
            <rabbit:reply-listener/>
        </rabbit:template>
    
        <rabbit:admin connection-factory="connectionFactory"/>
    
        <rabbit:queue id="requestQueue" name="REQUEST.QUEUE" />
        <rabbit:queue id="replyQueue" name="RESPONSE.QUEUE" />
    
        <rabbit:direct-exchange name="fdms.exchange" durable="true" auto-delete="false">
            <rabbit:bindings>
                <rabbit:binding queue="RESPONSE.QUEUE" key="response.key" />
            </rabbit:bindings>
        </rabbit:direct-exchange>
    </beans>
    

    SpringReceive.java

    import org.springframework.amqp.core.Message;
    import org.springframework.amqp.core.MessageBuilder;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class SpringReceive {
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("cslclient.xml");
        SimpleMessageListenerContainer serviceListenerContainer =     context.getBean("serviceListenerContainer", SimpleMessageListenerContainer.class);
        serviceListenerContainer.start();
        }
    }
    

1 个答案:

答案 0 :(得分:2)

您可以将RabbitTemplate.sendAndReceive()(或convertSendAndReceive())与回复侦听器容器(Docs here)一起使用;模板将为您处理相关性。

如果您使用的是Spring Integration,请使用带有适当配置的兔子模板的出站网关。