在redis中可以同时订阅多个频道,有消息发布时redis会发出通知。jedis中提供了JedisPubSub抽象类来提供发布/订阅的机制,在实际应用中需要实现JedisPubSub类。
示例代码:
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.JedisSentinelPool;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Redis发布订阅模式Test
* @author j.tommy
* @date 2016-09-07 10:46.
*/
public class RedisPubSubTest {
public static final Logger logger = Logger.getLogger(RedisPubSubTest.class);
public static final String CHANNEL_NAME = "testChannel";
static class Publisher {
private Logger logger = Logger.getLogger(Publisher.class);
private Jedis jedis;
public Publisher(Jedis jedis) {
this.jedis = jedis;
}
public void start() {
logger.info("Type your message (quit for terminate)");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String line = reader.readLine();
if (!"quit".equals(line)) {
jedis.publish(RedisPubSubTest.CHANNEL_NAME, line);
} else {
break;
}
}
} catch (IOException e) {
logger.error("IO failure while reading input, e");
}
}
}
static class Subcriber extends JedisPubSub {
private Logger logger = Logger.getLogger(Publisher.class);
@Override
public void onMessage(String channel, String message) {
logger.info("Message received.Channel=" + channel + ",message=" + message);
}
@Override
public void onPMessage(String s, String s1, String s2) {
}
@Override
public void onSubscribe(String s, int i) {
}
@Override
public void onUnsubscribe(String s, int i) {
}
@Override
public void onPUnsubscribe(String s, int i) {
}
@Override
public void onPSubscribe(String s, int i) {
}
}
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_redis.xml");
JedisSentinelPool jedisSentinelPool = ac.getBean(JedisSentinelPool.class);
final Jedis subcriberJedis = jedisSentinelPool.getResource();
// 订阅频道
new Thread(new Runnable() {
@Override
public void run() {
try {
logger.info("Subscribing to " + CHANNEL_NAME + ",this thread will be blocked.");
subcriberJedis.subscribe(new Subcriber(),CHANNEL_NAME); // 会一直阻塞在这一行
logger.info("Subscribing ended. "); // 不会执行这一句。
} catch (Exception e) {
logger.error("Subcribe channel failed." ,e);
}
}
}).start();
// 发布信息
Jedis publisherJedis = jedisSentinelPool.getResource();
new Publisher(publisherJedis).start();
}
}
参考:http://outofmemory.cn/code-snippet/3866/redis-dingyue-publish-example