redis 发布订阅模式

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

Redis 客户端可以订阅任意数量的频道。

以下实例演示了发布订阅是如何工作的,需要开启两个 redis-cli 客户端:
在我们实例中我们创建了订阅频道名为 sms:

SUBSCRIBE sms 

在这里插入图片描述

现在,我们先重新开启个 redis 客户端,然后在同一个频道 sms发布两次消息,订阅者就能接收到消息:

PUBLISH sms "hello sms"

在这里插入图片描述
订阅者的客户端会显示如下消息
在这里插入图片描述

java客户端

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sunyuqi</groupId>
    <artifactId>redis_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> 
    </parent>
    <properties>
        <java.version>9</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

配置文件

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0

消息监听类1

package com.sunyuqi.pubsub;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

@Component
@Profile("pubsub")
public class SmsChannelListener1 {
    
    

    @Autowired
    RedisTemplate redisTemplate;

    @PostConstruct
    public void setup() {
    
    
        redisTemplate.execute(new RedisCallback() {
    
    
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
    
    
                connection.subscribe((message, pattern) -> {
    
    
                    System.out.println("监听器1收到消息: " + message);
                }, "sms".getBytes());
                return null;
            }
        });
    }
}

消息监听类2

package com.sunyuqi.pubsub;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Profile("pubsub")
@Configuration
public class SmsChannelListener2 {
    
    
    // 定义监听器
    @Bean
    public RedisMessageListenerContainer smsMessageListener(RedisConnectionFactory redisConnectionFactory) {
    
    
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisConnectionFactory);
        SmsSendListener smsSendListener = new SmsSendListener();
        container.addMessageListener(smsSendListener, Arrays.asList(new ChannelTopic("sms")));
        return container;
    }

    class SmsSendListener implements MessageListener {
    
    
        @Override
        public void onMessage(Message message, byte[] pattern) {
    
    
            System.out.println("监听器2收到消息: " + message);
        }
    }
}

测试类

package com.sunyuqi.pubsub;

import com.sunyuqi.SpringbootApplicationDemo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplicationDemo.class)
@ActiveProfiles("pubsub")
public class PubsubTest {
    
    

    @Autowired
    RedisTemplate redisTemplate;

    @Test
    public void test1() throws InterruptedException {
    
    
        System.out.println("开始测试发布订阅机制");
        redisTemplate.execute(new RedisCallback<Long>() {
    
    
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
    
    
                // 发送通知
                Long received = connection.publish("sms".getBytes(), "hello world".getBytes());
                return received;
            }
        });
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42494845/article/details/108897194