人人人妻人人人妻人人人,99精品国产综合久久久久五月天 ,欧美白人最猛性XXXXX,日韩AV无码免费播放

News新聞

業(yè)界新聞動態(tài)、技術前沿
Who are we?

您的位置:首頁      樂道系統(tǒng)FAQ      php中Redis的應用--消息傳遞

php中Redis的應用--消息傳遞

標簽: 發(fā)布日期:2017-03-28 00:00:00 267
【CLI】利用Curl下載文件實時進度條顯示的實現(xiàn)

閱讀目錄

1、摘要

2、實現(xiàn)方法

3、一對一消息傳遞

4、多對多消息傳遞

1、摘要

消息傳遞這一應用廣泛存在于各個網站中,這個功能也是一個網站必不可少的。常見的消息傳遞應用有,新浪微博中的@我呀、給你評論然后的提示呀、贊贊贊提示、私信呀、甚至是發(fā)微博分享的新鮮事;知乎中的私信呀、live發(fā)送過來的消息、知乎團隊消息呀等等。

2、實現(xiàn)方法

消息傳遞即兩個或者多個客戶端在相互發(fā)送和接收消息。

通常有兩種方法實現(xiàn):

第一種為消息推送。Redis內置有這種機制,publish往頻道推送消息、subscribe訂閱頻道。這種方法有一個缺點就是必須保證接收者時刻在線(即是此時程序不能停下來,一直保持監(jiān)控狀態(tài),假若斷線后就會出現(xiàn)客戶端丟失信息)

第二種為消息拉取。所謂消息拉取,就是客戶端自主去獲取存儲在服務器中的數(shù)據(jù)。Redis內部沒有實現(xiàn)消息拉取這種機制。因此我們需要自己手動編寫代碼去實現(xiàn)這個功能。

在這里我們,我們進一步將消息傳遞再細分為一對一的消息傳遞,多對多的消息傳遞(群組消息傳遞)。

【注:兩個類的代碼相對較多,因此將其折疊起來了】

3、一對一消息傳遞

例子1:一對一消息發(fā)送與獲取

模塊要求:

1、提示有多少個聯(lián)系人發(fā)來新消息

2、信息包含發(fā)送人、時間、信息內容

3、能夠獲取之前的舊消息

4、并且消息能夠保持7天,過期將會被動觸發(fā)刪除

Redis實現(xiàn)思路:

1、新消息與舊消息分別采用兩個鏈表來存儲

2、原始消息的結構采用數(shù)組的形式存放,并且含有發(fā)送人、時間戳、信息內容

3、在推入redis的鏈表前,需要將數(shù)據(jù)轉換為json類型然后再進行存儲

4、在取出新信息時應該使用rpoplpush來實現(xiàn),將已讀的新消息推入舊消息鏈表中

5、取出舊消息時,應該用舊消息的時間與現(xiàn)在的時間進行對比,若超時,則直接刪除后面的全部數(shù)據(jù)(因為數(shù)據(jù)是按時間一個一個壓進鏈表中的,所以對于時間是有序排列的)

數(shù)據(jù)存儲結構圖:

PHP的實現(xiàn)代碼:

#SinglePullMessage.class.php

<?php
#單接接收者接收消息
class SinglePullMessage
{
 private $redis=''; #存儲redis對象
 /**
 * @desc 構造函數(shù)
 * 
 * @param $host string | redis主機
 * @param $port int | 端口
 */
 public function __construct($host,$port=6379)
 {
 $this->redis=new Redis();
 $this->redis->connect($host,$port);
 } 
 /**
 * @desc 發(fā)送消息(一個人)
 * 
 * @param $toUser string | 接收人
 * @param $messageArr array | 發(fā)送的消息數(shù)組,包含sender、message、time 
 *
 * @return bool
 */
 public function sendSingle($toUser,$messageArr)
 {
 $json_message=json_encode($messageArr); #編碼成json數(shù)據(jù)
 return $this->redis->lpush($toUser,$json_message); #將數(shù)據(jù)推入鏈表 
 }
 /**
 * @desc 用戶獲取新消息
 *
 * @param $user string | 用戶名
 *
 * @return array 返回數(shù)組,包含多少個用戶發(fā)來新消息,以及具體消息
 */
 public function getNewMessage($user)
 {
 #接收新信息數(shù)據(jù),并且將數(shù)據(jù)推入舊信息數(shù)據(jù)鏈表中,并且在原鏈表中刪除
 $messageArr=array();
 while($json_message=$this->redis->rpoplpush($user, 'preMessage_'.$user))
 {
  $temp=json_decode($json_message); #將json數(shù)據(jù)變成對象
  $messageArr[$temp->sender][]=$temp; #轉換成數(shù)組信息
 }
 if($messageArr)
 {
  $arr['count']=count($messageArr); #統(tǒng)計有多少個用戶發(fā)來信息
  $arr['messageArr']=$messageArr;
  return $arr;
 }
 return false;
 }
 public function getPreMessage($user)
 {
 ##取出舊消息
 $messageArr=array();
 $json_pre=$this->redis->lrange('preMessage_'.$user, 0, -1); #一次性將全部舊消息取出來
 foreach ($json_pre as $k => $v) 
 {
  $temp=json_decode($v);  #json反編碼
  $timeout=$temp->time+60*60*24*7; #數(shù)據(jù)過期時間 七天過期
  if($timeout<time())  #判斷數(shù)據(jù)是否過期
  {
  if($k==0)   #若是最遲插入的數(shù)據(jù)都過期了,則將所有數(shù)據(jù)刪除
  {
   $this->redis->del('preMessage_'.$user);
   break;
  }
  $this->redis->ltrim('preMessage_'.$user, 0, $k); #若檢測出有過期的,則將比它之前插入的所有數(shù)據(jù)刪除
  break;
  }
  $messageArr[$temp->sender][]=$temp;
 }
 return $messageArr;
 }
 /**
 * @desc 消息處理,沒什么特別的作用。在這里這是用來處理數(shù)組信息,然后將其輸出。 
 *
 * @param $arr array | 需要處理的信息數(shù)組
 *
 * @return 返回打印輸出
 */
 public function dealArr($arr)
 {
 foreach ($arr as $k => $v) 
 {
  foreach ($v as $k1 => $v2) 
  {
  echo '發(fā)送人:'.$v2->sender.' 發(fā)送時間:'.date('Y-m-d h:i:s',$v2->time).'<br/>';
  echo '消息內容:'.$v2->message.'<br/>';
  }
  echo "<hr/>";
 }
 }
}