Java笔记-使用RabbitMQ的Java接口实现topic(主题模式)

24 篇文章 3 订阅

目录

 

 

基本概念

代码与实例


 

基本概念

实现的就是官方给出的这个模型:

Topic exchange:将路由和某模式匹配

其中

#:匹配一个或多个

*:匹配一个

比如下面要举得这个例子

交换机设置为topic模式,生产者生成的消息的路由键值为goods.XXXX

其中XXXX,可能为add、delete、update、modify等

队列一绑定的是goods.add

队列二绑定的是goods.#

这样话,如果生产者生产一个路由键值为goods.add的消息,辣么2个队列都将会收到。

如果生产者生成一个路由键值为goods.delete的消息,辣么只有1个队列将会收到。

 

代码与实例

当生产者和消费者跑起来后,对应的RabbitMQ交换机如下:

可见有2个队列,一个绑定的路由键为goods.add

一个绑定的路由键为goods.#

当生产者发送的键值为goods.add时:

两个消费者都可以收到:

当生产者发送的键值为goods.delete时:

只有消费者二可以收到,消费者一和以前一样

源码如下:

Recv1.java

package topic;

import com.rabbitmq.client.*;
import util.ConnectionUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Recv1 {

    private static final String EXCHANGE_NAME = "test_exchange_topic";
    private static final String QUEUE_NAME = "test_queue_topic_1";

    public static void main(String[] args) throws IOException, TimeoutException {

        Connection connection = ConnectionUtils.getConnection();
        final Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.add");

        channel.basicQos(1);

        Consumer consumer = new DefaultConsumer(channel){

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                String msg = new String(body, "utf-8");
                System.out.println("[1] Recv msg : " + msg);


                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("[1] done");
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }
        };

        boolean autoAck = false;
        channel.basicConsume(QUEUE_NAME, autoAck, consumer);
    }
}

Recv2.java

package topic;

import com.rabbitmq.client.*;
import util.ConnectionUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Recv2 {

    private static final String EXCHANGE_NAME = "test_exchange_topic";
    private static final String QUEUE_NAME = "test_queue_topic_2";

    public static void main(String[] args) throws IOException, TimeoutException {

        Connection connection = ConnectionUtils.getConnection();
        final Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.#");

        channel.basicQos(1);

        Consumer consumer = new DefaultConsumer(channel){

            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

                String msg = new String(body, "utf-8");
                System.out.println("[2] Recv msg : " + msg);


                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("[2] done");
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }
        };

        boolean autoAck = false;
        channel.basicConsume(QUEUE_NAME, autoAck, consumer);
    }
}

Send.java

package topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import util.ConnectionUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Send {

    private static final String EXCHANGE_NAME = "test_exchange_topic";

    public static void main(String[] args) throws IOException, TimeoutException {

        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");

        String msgString = "goods ... ... ...";
        channel.basicPublish(EXCHANGE_NAME, "goods.delete", null, msgString.getBytes());
        System.out.println("send msg :" + msgString);
        channel.close();
        connection.close();
    }
}

ConnectionUtils.java

package util;

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class ConnectionUtils {

    public static Connection getConnection() throws IOException, TimeoutException {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(5672);
        factory.setVirtualHost("/vhost_cff");
        factory.setUsername("cff");
        factory.setPassword("123");

        return factory.newConnection();
    }
}

源码打包下载地址:

https://github.com/fengfanchen/Java/tree/master/TopicModel

实现 Spring Boot、RabbitMQ 和 WebSocket 结合的方式主要有以下几个步骤: 1. 创建 Spring Boot 项目,添加 RabbitMQ 和 WebSocket 的相关依赖。 2. 创建 RabbitMQ 队列和交换机,用于发送消息。 3. 创建 WebSocket 配置类,配置 WebSocket 的相关参数。 4. 创建 WebSocket 处理器类,处理 WebSocket 的连接、消息发送等操作。 5. 创建 RabbitMQ 消息监听器类,监听 RabbitMQ 队列中的消息,将消息发送给 WebSocket 处理器。 下面是具体的实现步骤: 1. 创建 Spring Boot 项目,添加 RabbitMQ 和 WebSocket 的相关依赖。 在 pom.xml 中添加以下依赖: ```xml <dependencies> <!-- RabbitMQ 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <!-- WebSocket 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> </dependencies> ``` 2. 创建 RabbitMQ 队列和交换机,用于发送消息。 在 RabbitMQ 中创建一个交换机和一个队列,然后将队列绑定到交换机上。这里我们使用 RabbitMQ 的默认交换机和队列。 ```java @Configuration public class RabbitMQConfig { @Bean public Queue queue() { return new Queue("websocket"); } @Bean public DirectExchange exchange() { return new DirectExchange(""); } @Bean public Binding binding(Queue queue, DirectExchange exchange) { return BindingBuilder.bind(queue).to(exchange).with("websocket"); } } ``` 3. 创建 WebSocket 配置类,配置 WebSocket 的相关参数。 ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS(); } } ``` 4. 创建 WebSocket 处理器类,处理 WebSocket 的连接、消息发送等操作。 ```java @Component public class WebSocketHandler implements WebSocketHandler { private static final Logger logger = LoggerFactory.getLogger(WebSocketHandler.class); private SimpMessagingTemplate messagingTemplate; @Autowired public WebSocketHandler(SimpMessagingTemplate messagingTemplate) { this.messagingTemplate = messagingTemplate; } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.info("WebSocket connected: {}", session.getId()); } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { logger.info("WebSocket received message: {}", message.getPayload()); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { logger.error("WebSocket transport error: {}", exception.getMessage()); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.info("WebSocket disconnected: {}", session.getId()); } @Override public boolean supportsPartialMessages() { return false; } public void sendMessage(String message) { messagingTemplate.convertAndSend("/topic/messages", message); } } ``` 5. 创建 RabbitMQ 消息监听器类,监听 RabbitMQ 队列中的消息,将消息发送给 WebSocket 处理器。 ```java @Component public class RabbitMQListener { private static final Logger logger = LoggerFactory.getLogger(RabbitMQListener.class); private WebSocketHandler webSocketHandler; @Autowired public RabbitMQListener(WebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @RabbitListener(queues = "websocket") public void handleMessage(String message) { logger.info("RabbitMQ received message: {}", message); webSocketHandler.sendMessage(message); } } ``` 至此,Spring Boot、RabbitMQ 和 WebSocket 结合的实现就完成了。我们可以通过 RabbitMQ 发送消息到队列,然后监听器会将消息发送给 WebSocket 处理器,处理器再将消息发送给 WebSocket 客户端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值