Redis的发布订阅

本文详细介绍Redis发布订阅模式的工作原理,包括如何在命令行中操作,以及通过Java代码实现的客户端订阅者和发布者实例。通过步骤展示了如何创建JedisPubSub订阅者,启动子线程订阅频道,并观察发布者发送消息的过程。
摘要由CSDN通过智能技术生成

什么是发布订阅

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

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

Redis 的发布和订阅

1.客户端可以订阅频道如下图
在这里插入图片描述
2.当给这个频道发布消息后,消息就会发送给订阅的客户端
在这里插入图片描述

发布订阅命令行实现

  1. 打开一个客户端订阅 channel1
    subscribe channel1
    在这里插入图片描述

  2. 打开另一个客户端,给 channel1 发布消息 hello
    publish channel1 hello
    在这里插入图片描述

  3. 打开第一个客户端可以看到发送的消息
    在这里插入图片描述

注意:发布的消息没有持久化,如果在订阅的客户端收不到hello,只能厚道订阅后发布的消息。也就是说,订阅前的消息是收不到的。

代码实现

导入依赖包

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

编写订阅者

创建订阅者需要继承抽象类JedisPubSub,然后重写以下三个方法

package com.wpp.redis_publish_subscribe.subscrib;

import redis.clients.jedis.JedisPubSub;

/**
 * @Author wpp
 * @Date 2022/05/07/11:40
 * @Description 订阅者
 */
public class Subscriber extends JedisPubSub {

    public  Subscriber(){}

    @Override
    public void onMessage(String channel, String message) {//收到消息会调用
        System.out.println("从频道:"+ channel + "收到发布的消息:" + message);
    }

    @Override
    public void onSubscribe(String channel, int subscribedChannels) {//订阅了频道会调用
        System.out.println("订阅频道成功");
    }

    @Override
    public void onUnsubscribe(String channel, int subscribedChannels) {//取消订阅 会调用
        System.out.println("取消订阅");
    }
}

编写一个子线程

这个子线程主要用于创建一个订阅者并去订阅某个频道

package com.wpp.redis_publish_subscribe.channerl;

import com.wpp.redis_publish_subscribe.subscrib.Subscriber;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @Author wpp
 * @Date 2022/05/07/13:14
 * @Description 订阅频道
 */
public class SubThread extends Thread{

    private final JedisPool jedisPool;

    private final Subscriber subscriber = new Subscriber();

    private final String channel = "mychannel";

    public SubThread(JedisPool jedisPool) {
        super("SubThread");
        this.jedisPool = jedisPool;
    }

    @Override
    public void run() {
        System.out.println("准备订阅");
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();//取出一个连接
            jedis.subscribe(subscriber,channel);//通过subscribe 的api去订阅,入参是订阅者和频道名

        } catch (Exception e) {
            System.out.println("订阅失败");
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}

编写发布者

我们的发布者需要继承线程类

package com.wpp.redis_publish_subscribe.publish;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author wpp
 * @Date 2022/05/07/11:31
 * @Description 发布者
 */
public class Publisher extends Thread {

    private final JedisPool jedisPool;

    public Publisher(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    @Override
    public void run() {
        System.out.println("发布者。。。");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Jedis jedis = jedisPool.getResource();//连接池中取出一个连接
        while (true) {
            String line = null;
            try {
                line = reader.readLine();
                if (!"quit".equals(line)) {
                    jedis.publish("mychannel",line);//从 mychannel 的频道上推送消息
                } else {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

测试

最后我们来做个测试喽

package com.wpp.redis_publish_subscribe;

import com.wpp.redis_publish_subscribe.channerl.SubThread;
import com.wpp.redis_publish_subscribe.publish.Publisher;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @Author wpp
 * @Date 2022/05/07/14:20
 * @Description
 */
public class Demo {
    public static void main(String[] args) {
        JedisPool jedisPool = new JedisPool(new JedisPoolConfig(),"Redis地址",6379,0,"Redis密码",0);

        SubThread subThread = new SubThread(jedisPool);//订阅者
        subThread.start();

        Publisher publisher = new Publisher(jedisPool);//发布者
        publisher.start();
    }
}

运行项目之后:
在这里插入图片描述
在控制台输入hello,结果如下:
在这里插入图片描述
ok,完美!为了模拟更真实点,完全可以把发布者和订阅者写在两个不同的项目中试验。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值