redis提供了订阅发布功能,但是提供的尤其的简单与轻量级。实践当中如果不进行扩展,能应用的程度暂时不好说。。。。
实现中是消息发送者将消息发送给频道,然后订阅的频道的客户收到响应的消息。订阅可以进行精确订阅,也可以通过表达式进行订阅。
通过表达式的订阅模式,在响应的时候会与精确订阅有些不同,会多返回一个字段,来展示是通过哪个表达式订阅的频道进行返回。
Pub/Sub(发布/订阅)涉及到的命令:
- PUBLISH:推送消息。
- PUBLISH channel message:将信息 message 发送到指定的频道 channel 。接收到信息 message
- PUBSUB:查看频道等订阅状态。
- PUBSUB channels [passern]:列出当前的活跃频道。活跃频道指的是那些至少有一个订阅者的频道, 订阅模式的客户端不计算在内。
- PUBSUB numsub [channel1...channelN]:返回给定频道的订阅者数量, 订阅模式的客户端不计算在内。返回:一个多条批量回复(Multi-bulk reply),回复中包含给定的频道,以及频道的订阅者数量。
- PUBSUB numpat:返回订阅模式的数量。
- 需要注意的是:上述的三个命令,有的是针对订阅频道,有的是针对订阅模式!
- PSUBSCRIBE:订阅模式。
- PSUBSCRIBE pattern [pattern ...]:订阅一个或多个符合给定模式的频道。用*匹配。返回:1订阅成功 2订阅模式 3订阅数。 如果有推送消息过来的时候。 1消息 2信息匹配模式 3频道 4信息
- PUNSUBSCRIBE:取消订阅模式。
- PUNSUBSCRIBE [pattern [pattern ...]]:退订订阅模式,如果不加参数,退订所有模式。
- SUBSCRIBE:订阅频道。
- UNSUBSCRIBE:取消订阅频道。
- 上述两个命令就没有太多可说的了啦。参考订阅模式吧。
Redis的JAVA API中jedis提供了关于pub/sub的操作类。可以继承JedisPubSub。
public class Subscriber extends JedisPubSub{
private static final Logger LOGGER = Logger.getLogger(Subscriber.class);
/**
* 订阅频道
*/
@Override
public void subscribe(String... channels) {
LOGGER.info("on Subscribe");
}
/**
* 订阅的频道消息
*/
@Override
public void onMessage(String channel, String message) {
LOGGER.info(String.format("Message. Channel: %s, Msg: %s", channel, message));
}
/**
*订阅模式的消息
*/
@Override
public void onPMessage(String pattern, String channel, String message) {
LOGGER.info(String.format("Message. Channel: %s, Pattern : %s ,Msg: %s", channel,pattern, message));
}
}
public class RedisPubSub{
private Jedis jedis;
public RedisPubSub(Jedis jedis){
this.jedis = jedis;
}
public List<String> pubsubChannels(String pattern){
return jedis.pubsubChannels(pattern);
}
public Map<String,String> pubsubNumSub(String ...channels){
return jedis.pubsubNumSub(channels);
}
public Long pubsubNumPat(){
return jedis.pubsubNumPat();
}
}
public class Test {
public static final String REDIS_HOST = "127.0.0.1";
public static final int REDIS_PORT = 6379;
private final static JedisPoolConfig POOL_CONFIG = new JedisPoolConfig();
private final static JedisPool JEDIS_POOL = new JedisPool(POOL_CONFIG,REDIS_HOST,REDIS_PORT,0);
public static void main(String[] args) {
final Jedis jedis = JEDIS_POOL.getResource();
jedis.subscribe(new Subscriber(), "aa");
}
}
redis的pub/sub如果不进行扩展的时候使用方式还是比较简单。注意的是,subscribe的时候线程是会被阻塞的。