redis的訂閱與發布在java中的應用

來源:互聯網
上載者:User

標籤:resource   lis   ace   private   xtend   final   start   ora   頻道   

Redis為我們提供了publish/subscribe(發布/訂閱)功能。我們可以對某個channel(頻道)進行subscribe(訂閱),當有人在這個channel上publish(發布)訊息時,redis就會通知我們,這樣我們可以收到別人發布的訊息。
作為Java的redis用戶端,Jedis提供了publish/subscribe的介面。本文講述如何使用Jedis來實現redis的publish/subscribe。

定義一個 Subscriber

Jedis定義了抽象類別JedisPubSub,在這個類中,定義publish/subsribe的回調方法。通過繼承JedisPubSub類並重新實現這些回調方法,當publish/subsribe事件發生時,我們可以定製自己的處理邏輯。

在以下例子中,我們定義了Subscriber類,這個類繼承了JedisPubSub類,並重新實現了其中的回調方法。

import redis.clients.jedis.JedisPubSub;public class Subscriber extends JedisPubSub {    public Subscriber() {    }    public void onMessage(String channel, String message) {        System.out.println(String.format("receive redis published message, channel %s, message %s", channel, message));    }    public void onSubscribe(String channel, int subscribedChannels) {        System.out.println(String.format("subscribe redis channel success, channel %s, subscribedChannels %d",                 channel, subscribedChannels));    }    public void onUnsubscribe(String channel, int subscribedChannels) {        System.out.println(String.format("unsubscribe redis channel, channel %s, subscribedChannels %d",                 channel, subscribedChannels));    }}

定義SubThread線程類

由於Jedis的subscribe操作是阻塞的,因此,我們另起一個線程來進行subscribe操作。

import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;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(String.format("subscribe redis, channel %s, thread will be blocked", channel));        Jedis jedis = null;        try {            jedis = jedisPool.getResource();            jedis.subscribe(subscriber, channel);        } catch (Exception e) {            System.out.println(String.format("subsrcibe channel error, %s", e));        } finally {            if (jedis != null) {                jedis.close();            }        }    }}
在上面的代碼中,我們從JedisPool擷取一個Jedis執行個體,並使用這個Jedis執行個體進行subscribe的操作。
Jedissubscribe的聲明如下:
public void subscribe(final JedisPubSub jedisPubSub, final String… channels)
第一個參數接受一個JedisPubSub對象,第二個參數指定對哪個頻道進行訂閱。上例中,我們把我們定義的Subscriber對象傳給subscribe方法。
當publish/subscribe的事件發生時,會自動調用我們Subscriber的方法。
定義Publisher類

Publisher類接受使用者的輸入,並將輸入發布到channel。當使用者輸入”quit”後,輸入結束。

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;public class Publisher {    private final JedisPool jedisPool;    public Publisher(JedisPool jedisPool) {        this.jedisPool = jedisPool;    }    public void start() {        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);                } else {                    break;                }            } catch (IOException e) {                e.printStackTrace();            }         }    }}
定義入口代碼

如下是我們的程式入口代碼。

import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class PubSubDemo {    public static void main( String[] args )    {        // 替換成你的reids地址和連接埠        String redisIp = "127.0.0.1";        int reidsPort = 6379;        JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), redisIp, reidsPort);        System.out.println(String.format("redis pool is starting, redis ip %s, redis port %d", redisIp, reidsPort));        SubThread subThread = new SubThread(jedisPool);        subThread.start();        Publisher publisher = new Publisher(jedisPool);        publisher.start();    }}

在上面的代碼中,我們首先產生了一個JedisPool的redis串連池,這是由於Jedis不是安全執行緒的,JedisPool是安全執行緒的。而我們的程式在主線程和訂閱線程(SubThread)均需要使用Jedis,故在程式中我們使用JedisPool。
由於Jedis的subcribe操作是阻塞的,故我們另起了一個線程來進行subcribe操作。
通過調用Publisher::start()方法,接受使用者的輸入,並publish到指定的channel。



redis的訂閱與發布在java中的應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.