發布訂閱(pub/sub)是一種訊息通訊模式,主要的目的是解耦訊息發行者和訊息訂閱者之間的耦合,這點和設計模式中的觀察者模式比較相似。pub/sub不僅僅解決發行者和訂閱者直接代碼層級耦合也解決兩者在物理部署上的耦合。redis作為一個pub/sub的server,在訂閱者和發行者之間起到了訊息路由的功能。訂閱者可以通過subscribe和psubscribe命令向redis server訂閱自己感興趣的訊息類型,redis將訊息類型稱為通道(channel)。當發行者通過publish命令向redis server發送特定類型的訊息時。訂閱該訊息類型的全部client都會收到此訊息。這裡訊息的傳遞是多對多的。一個client可以訂閱多個channel,也可以向多個channel發送訊息。
下面做個實驗。這裡使用3不同的client, client1用於訂閱tv1這個channel的訊息,client2用於訂閱tv1和tv2這2個chanel的訊息,client3用於發布tv1和tv2的訊息。
下面將詳細的解釋一下上面的例子
1、client1訂閱了tv1這個channel這個頻道的訊息,client2訂閱了tv1和tv2這2個頻道的訊息
2、client3 是用於發布tv1和tv2這2個頻道的訊息發行者
3、接下來我們在client3發布了一條訊息”publish tv1 program1”,大家可以看到這條訊息是發往tv1這個頻道的
4、理所當然的client1和client2都接收到了這個頻道的訊息
5、 然後client3又發布了一條訊息”publish tv2 program2”,這條訊息是發往tv2的,由於client1並沒有訂閱tv1,所以client1的結果中並沒有顯示出任何結果,但client2訂閱了這個頻道,所以client2是會有返回結果的。
我們也可以用psubscribe tv*的方式批量訂閱以tv開頭的頻道的內容。
看完這個小例子後應該對pub/sub功能有了一個感性的認識。需要注意的是當一個串連通過subscribe或者psubscribe訂閱通道後就進入訂閱模式。在這種模式除了再訂閱額外的通道或者用unsubscribe或者punsubscribe命令退出訂閱模式,就不能再發送其他命令。另外使用 psubscribe命令訂閱多個萬用字元通道,如果一個訊息匹配上了多個通道模式的話,會多次收到同一個訊息。
下面給出PHP的實現代碼:
<?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); $channel = $argv[1]; // channel $msg = $argv[2]; // msg $redis->publish('channel'.$channel, $msg); ?>
<?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); $channel = $argv[1]; // channel $redis->subscribe(array('channel'.$channel), 'callback'); function callback($instance, $channelName, $message) { echo $channelName, "==>", $message,PHP_EOL; } ?>