想不到redis会提供pub/sub功能。消息订阅发布模式就不说了,跟观察者模式很接近。
redis 作为一个publish/subscribe server,起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,当发布者通过publish命令向redis server发送特定类型的消息时。订阅该消息类型的全部client都会收到此消息。这里消息的传递是多对多的。一个client可以订阅多个channel,也可以向多个channel发送消息。
下面用代码做一下试验。采用的是jedis客户端,代码如下
public class PubSubTest extends JedisPubSub {
@Override
public void onMessage(String channel, String message) {
// TODO Auto-generated method stub
super.onMessage(channel, message);
System.out.println("收到渠道为"+channel+"的消息:"+message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
super.onSubscribe(channel, subscribedChannels);
System.out.println("订阅渠道"+channel);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
super.onUnsubscribe(channel, subscribedChannels);
System.out.println("取消订阅渠道"+channel);
}
}
代码解读,创建一个类,继承自JedisPubSub,这是jedis中实现pub/sub的类。该类中会有一些方法需要重写。比如onMessage,收到订阅消息时会调用该类中的方法。onSubscribe,订阅某个渠道时,会调用该方法。onUnsubscribe,取消订阅某个渠道时,调用该方法。
然后在main方法里面调用以下代码
jedis=new Jedis("localhost");
PubSubTest test=new PubSubTest();
jedis.subscribe(test, "cctv5");
这段代码很简单,就是订阅名称为cctv5的渠道。当我在其他客户端publish消息时,就会触发onMessage方法。
看完这个小例子后应该对pub/sub功能有了一个感性的认识。需要注意的是当一个连接通过subscribe或者psubscribe订阅通道后就进入订阅模式。在这种模式除了再订阅额外的通道或者用unsubscribe或者punsubscribe命令退出订阅模式,就不能再发送其他命令。另外使用psubscribe命令订阅多个通配符通道,如果一个消息匹配上了多个通道模式的话,会多次收到同一个消息。
redis的pub/sub还是有点太单薄(实现才用150行代码)。在安全,认证,可靠性这方便都没有太多支持。