想不到redis會(huì)提供pub/sub功能。消息訂閱發(fā)布模式就不說了,跟觀察者模式很接近。
redis 作為一個(gè)publish/subscribe server,起到了消息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis server訂閱自己感興趣的消息類型,當(dāng)發(fā)布者通過publish命令向redis server發(fā)送特定類型的消息時(shí)。訂閱該消息類型的全部client都會(huì)收到此消息。這里消息的傳遞是多對(duì)多的。一個(gè)client可以訂閱多個(gè)channel,也可以向多個(gè)channel發(fā)送消息。
下面用代碼做一下試驗(yàn)。采用的是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);
}
}
代碼解讀,創(chuàng)建一個(gè)類,繼承自JedisPubSub,這是jedis中實(shí)現(xiàn)pub/sub的類。該類中會(huì)有一些方法需要重寫。比如onMessage,收到訂閱消息時(shí)會(huì)調(diào)用該類中的方法。onSubscribe,訂閱某個(gè)渠道時(shí),會(huì)調(diào)用該方法。onUnsubscribe,取消訂閱某個(gè)渠道時(shí),調(diào)用該方法。
然后在main方法里面調(diào)用以下代碼
jedis=new Jedis("localhost");
PubSubTest test=new PubSubTest();
jedis.subscribe(test, "cctv5");
這段代碼很簡(jiǎn)單,就是訂閱名稱為cctv5的渠道。當(dāng)我在其他客戶端publish消息時(shí),就會(huì)觸發(fā)onMessage方法。
看完這個(gè)小例子后應(yīng)該對(duì)pub/sub功能有了一個(gè)感性的認(rèn)識(shí)。需要注意的是當(dāng)一個(gè)連接通過subscribe或者psubscribe訂閱通道后就進(jìn)入訂閱模式。在這種模式除了再訂閱額外的通道或者用unsubscribe或者punsubscribe命令退出訂閱模式,就不能再發(fā)送其他命令。另外使用psubscribe命令訂閱多個(gè)通配符通道,如果一個(gè)消息匹配上了多個(gè)通道模式的話,會(huì)多次收到同一個(gè)消息。
redis的pub/sub還是有點(diǎn)太單?。▽?shí)現(xiàn)才用150行代碼)。在安全,認(rèn)證,可靠性這方便都沒有太多支持。