本篇文章給大家分享的是有關(guān)php中怎么利用redis實現(xiàn)消息發(fā)布訂閱,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)溝通電話:028-86922220,為您提供成都網(wǎng)站建設(shè)網(wǎng)頁設(shè)計及定制高端網(wǎng)站建設(shè)服務(wù),成都創(chuàng)新互聯(lián)網(wǎng)頁制作領(lǐng)域十載,包括主動防護網(wǎng)等多個方面擁有多年的網(wǎng)站營銷經(jīng)驗,選擇成都創(chuàng)新互聯(lián),為企業(yè)保駕護航!
Pub/Sub功能(means Publish, Subscribe)即發(fā)布及訂閱功能
基于事件的系統(tǒng)中,Pub/Sub是目前廣泛使用的通信模型,它采用事件作為基本的通信機制,提供大規(guī)模系統(tǒng)所要求的松散耦合的交互模式:訂閱者(如客戶端)以事件訂閱的方式表達出它有興趣接收的一個事件或一類事件;發(fā)布者(如服務(wù)器)可將訂閱者感興趣的事件隨時通知相關(guān)訂閱者。
消息發(fā)布者,即publish客戶端,無需獨占鏈接,你可以在publish消息的同時,使用同一個redis-client鏈接進行其他操作(例如:INCR等)
消息訂閱者,即subscribe客戶端,需要獨占鏈接,即進行subscribe期間,redis-client無法穿插其他操作,此時client以阻塞的方式等待“publish端”的消息;這一點很好理解,因此subscribe端需要使用單獨的鏈接,甚至需要在額外的線程中使用。
當使用銀行卡消費的時候,銀行往往會通過微信、短信或郵件通知用戶這筆交易的信息,這便是一種發(fā)布訂閱模式,這里的發(fā)布是交易信息的發(fā)布,訂閱則是各個渠道。這在實際工作中十分常用,Redis 支持這樣的一個模式。
發(fā)布訂閱模式首先需要消息源,也就是要有消息發(fā)布出來,比如例子中的銀行通知。首先是銀行的記賬系統(tǒng),收到了交易的命令,成功記賬后,它就會把消息發(fā)送出來,這個時候,訂閱者就可以收到這個消息進行處理了,觀察者模式就是這個模式的典型應(yīng)用了。
訂閱,頻道為'chat'
發(fā)布消息
subscribe.php
connect("127.0.0.1",6379);//$redis->setOption(Redis::OPT_READ_TIMEOUT, -1); //redis方式設(shè)置不超時,推薦$redis->subscribe(['chan'],'callback'); //callback為回調(diào)函數(shù)名稱//$redis->subscribe(['chan'],array(new TestCall(),'callback') ); //如果回調(diào)函數(shù)是類中的方法名,這樣寫// 回調(diào)函數(shù),這里寫處理邏輯function callback($instance, $channelName, $message){ echo $channelName, "==>", $message, PHP_EOL; //$instance,即為上面創(chuàng)建的redis實例對象,在回調(diào)函數(shù)中,默認的這個參數(shù)就是,因此不需專門傳參。 這里除了SUBSCRIBE、PSUBSCRIBE、UNSUBSCRIBE、PUNSUBSCRIBE這4條命令之外其它命令都不能使用 //如果要使用redis中的其他命令,這樣實現(xiàn) $newredis = new Redis();$newredis->connect("127.0.0.1", 6379);echo $newredis->get('test') . PHP_EOL;$newredis->close(); //可以根據(jù)$channelName, $message,處理不同的業(yè)務(wù)邏輯 switch($chan) { case 'chan-1': ... break; case 'chan-2': ... break; } switch($message) { case 'msg1': ... break; case 'msg2': ... break; }}
publish.php
connect("127.0.0.1",6379); $redis->publish('chan','this is a message');
subscribe.php中設(shè)置不超時
方法1:ini_set('default_socket_timeout', -1);方法2: $redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
如果不設(shè)置不超時,60s后會報一個錯誤
PHP Fatal error: Uncaught RedisException: read error on connection to 127.0.0.1:6379 in subscribe.php:6
方式一的實現(xiàn),是通過臨時修改ini的配置值,default_socket_timeout默認為60s,default_socket_timeout是socket流的超時參數(shù),即socket流從建立到傳輸再到關(guān)閉整個過程必須要在這個參數(shù)設(shè)置的時間以內(nèi)完成,如果不能完成,那么PHP將自動結(jié)束這個socket并返回一個警告。
方式二是通過修改redis的配置項,因此僅對redis連接生效,相對于方式1,不會產(chǎn)生意外的對其他方法的影響。
redis的psubscribe支持通過模式匹配的方式實現(xiàn)批量訂閱,訂閱方式
回調(diào)函數(shù)寫函數(shù)名或者redis->psubscribe(['my*'],array(new TestCall(),'psubscribe')); //回調(diào)函數(shù)為類中的方法,類名寫你自己定義的類
subscribe.php
connect("127.0.0.1",6379);$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);//匹配方式1:發(fā)布可用$redis->publish('mymest','this is a message');//$redis->psubscribe(['my*'],'psubscribe'); //匹配方式2:發(fā)布可用$redis->publish('mydest','this is a message');//$redis->psubscribe(['my?est'],'psubscribe');//匹配方式3:發(fā)布可用$redis->publish('myaest','this is a message');或$redis->publish('myeest','this is a message');$redis->psubscribe(['my[ae]est'],'psubscribe');function psubscribe($redis, $pattern, $chan, $msg) { echo "Pattern: $pattern\n"; echo "Channel: $chan\n"; echo "Payload: $msg\n";}
模式匹配規(guī)則
支持以下幾種,以hello舉例:
h?llo subscribes to hello, hallo and hxllo
h*llo subscribes to hllo and heeeello
h[ae]llo subscribes to hello and hallo, but not hillo
特殊字符用\轉(zhuǎn)義
public function pubsub( argument )
pubsub獲取pub/sub系統(tǒng)的信息,$keyword可用為"channels", "numsub", 或者"numpat",三種,傳入不同的keyword返回的數(shù)據(jù)不同
* $redis->pubsub('channels'); // All channels 獲取所有的頻道,返回數(shù)組 * $redis->pubsub('channels', '*pattern*'); // Just channels matching your pattern,返回符合匹配模式的頻道 * $redis->pubsub('numsub', array('chan1', 'chan2')); // Get subscriber counts for 'chan1' and 'chan2' //返回每個訂閱頻道的數(shù)量,返回數(shù)組 * $redis->pubsub('numpat'); // Get the number of pattern subscribers 獲取模式匹配方式的訂閱
以上就是php中怎么利用redis實現(xiàn)消息發(fā)布訂閱,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。