首頁  >  文章  >  Java  >  什麼是Redis發布訂閱?

什麼是Redis發布訂閱?

PHP中文网
PHP中文网原創
2017-06-20 09:56:161598瀏覽

我想到使用Redis的訂閱發布模式是用來解決推播問題的~。

對於概念性的敘述,多多少少還是要提一下的:

什么是Redis发布订阅?Redis发布订阅是一种消息通信模式,发送者通过通道A发送消息message,订阅过通道A的客户端就可以接收到消息message。嗯度娘上面的解释要比我所说的好多了,而我所理解的就是:所谓的订阅发布模式,其实和我们看电视,听广播差不多,在我们没有调台(换频道)的时候,那个频道也是在传递消息的(发布)。我们换到那个频道上(订阅)就能接收到消息了。是的,虽然可能有些不恰当~

說明

本文中示例采用了三个客户端,以“品”字形排列,由上至下,由左至右分别为客户端1(c1),客户端2(c2),客户端3(c3).特此说明。

Redis訂閱與發布命令

首先聲明,有關Redis伺服器的搭建工作,請自行查閱相關資料進行環境搶建

聽說Redis中發布與訂閱只有簡單的6個命令。即:

  • PSUBSCRIBE pattern [pattern ...]

  • 訂閱一個或多個符合pattern格式的頻道

  • #PUBLISH channel message

  • ##發佈訊息到chanel中

  • PUBSUB subcommand [argument [argument ...]]

  • 查看訂閱與發布系統狀態

  • PUNSUBSCRIBE [pattern [pattern ...]]

  • 取消訂閱所有符合格式的頻道

  • SUBSCRIBE channel [channel ...]

  • 訂閱一個或多個頻道

  • UNSUBSCRIBE [channel [channel ...]]

  • #取消訂閱頻道

##範例1 - SUBSCRIBE

連接redis後鍵入指令

SUBSCRIBE study

這樣便訂閱了一個名為study的頻道。

接下來study頻道要發訊息啦。 ~~

##範例2 - PUBLISH


另開啟一個客戶端,我使用的是品字形佈局的最上面那個做為發布者,鍵入

PUBLISH study "message1-go go go"
可以看到,當客戶端1在study頻道發布消息時,客戶端2(已訂閱study頻道)可以接收到c1發布的消息,而客戶端3由於沒有訂閱study頻道,所以接收不到c1發送的消息。

範例3 - PSUBSCRIBE


現在,跟著部落客左手,右手一個慢動作。在c3中鍵入

PSUBSCRIBE study*
OK,現在在c1中鍵入

PUBLISH study "message2"
上結果圖:

c3採用的通配符的形式,也將study頻道給訂閱成功了。

接下來,在c1中繼續鍵入命令:

PUBLISH study:java "I hate java forever"
可以看到,使用psubscribe不僅將study頻道訂閱了,而且將以study為首的頻道也訂閱了。

範例4 - PUBSUB


在c1中鍵入pubsub channel,可以取得:

127.0.0.1:6379> PUBSUB channels

1) "study"
意為目前正在活躍的頻道。

Jedis實作訂閱發布者模式

好了,上面通过命令行熟悉了一下Redis中有关订阅发布者模式的相关命令。下面我们要将redis的订阅与发布者嵌入到项目中。

首先,我们使用jedis先订阅一个名为:study的频道

然後我們先從命令列進行訊息發布:

之後,我們使用jedis在專案中進行訊息發布:

我們可以進行正常的通訊~噢耶~

核心程式碼:


PublishMessage.java 用來開啟一個發佈訊息的執行緒

private Logger logger = LoggerFactory.getLogger(PublishMessage.class);

@Resource
private JedisCluster jedisCluster;

/**
 * 发布消息
 *
 * @param channel 频道
 * @param message 信息
 */
public void sendMessage(final String channel, final String message) {
    Thread thread = new Thread(() -> {
        Long publish = jedisCluster.publish(channel, message);
        logger.info("服务器在: {} 频道发布消息{} - {}", channel, message, publish);
    });
    logger.info("发布线程启动:");
    thread.setName("publishThread");
    thread.start();
}
ChatSubscribe.java用來處理訂閱相關事件,繼承自JedisPubSub

private Logger logger = LoggerFactory.getLogger(ChatSubscribe.class);

// 取得订阅的消息后的处理
@Override
public void onMessage(String channel, String message) {
    logger.info("订阅成功,接收到的消息为:频道-{},消息-{}", channel, message);
    RedisString.message = message;
}

// 取得按表达式的方式订阅的消息后的处理
@Override
public void onPMessage(String pattern, String channel, String message) {
    System.out.println("-----取得按表达式的方式订阅的消息后的处理-----");
    System.out.println(pattern + "=" + channel + "=" + message);
}

// 初始化按表达式的方式订阅时候的处理
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
    System.out.println("-----初始化按表达式的方式订阅时候的处理-----");
    System.out.println(pattern + "=" + subscribedChannels);
}

// 取消按表达式的方式订阅时候的处理
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
    System.out.println("-----取消按表达式的方式订阅时候的处理-----");
    System.out.println(pattern + "=" + subscribedChannels);
}

@Override
public void onPong(String pattern) {
    super.onPong(pattern);
}

// 初始化订阅时候的处理
@Override
public void onSubscribe(String channel, int subscribedChannels) {
    logger.info("初始化订阅信息:频道-{},订阅频道-{}", channel, subscribedChannels);
}

// 取消订阅时候的处理
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
    logger.info("已取消订阅频道{}", channel);
}
SubScribeMessage.java 訂閱頻道,取消頻道等動作類別

private Logger logger = LoggerFactory.getLogger(SubScribeMessage.class);

private ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

@Resource
private JedisCluster jedisCluster;
/**
     * 订阅频道
     *
     * @param channel          频道
     * @param roomSubListerner
     */
    public void subscribeChannel(final String channel, final ChatSubscribe roomSubListerner) {

        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                jedisCluster.subscribe(roomSubListerner, channel);
            }
        });
    }

jedisCluster是否封装工具类,取自各位看官,核心代码已给出,请各位看官根据自身业务与逻辑,自行更改与优化代码。

本次示例程序采用tomcat 9.0 + spring + springmvc

使用了诸如:@RestController,@GetMapping等相关注解,便于开发,有兴趣可自行查阅spring相关资料。

以上是什麼是Redis發布訂閱?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn