• php redis 处理websocket聊天记录


      1 <?php
      2 ini_set('display_errors', 'on');
      3 
      4 class chatClass {
      5     private $redis;
      6 
      7     //这个变量模拟用户当前状态,是否登录,是否可查看
      8     public $checkUserReadable = false;
      9 
     10     //构造函数链接redis数据库
     11     public function __construct() {
     12         $this -> redis = new Redis();
     13         $this -> redis -> connect('127.0.0.1', '6379');
     14         $this -> redis -> auth('***cnblogs.com/handle');
     15     }
     16 
     17     /*
     18     发送消息时保存聊天记录
     19     * 这里用的redis存储是list数据类型
     20     * 两个人的聊天用一个list保存
     21     *
     22     * @from 消息发送者id
     23     * @to 消息接受者id
     24     * @meassage 消息内容
     25     *
     26     * 返回值,当前聊天的总聊天记录数
     27     */
     28     public function setChatRecord($from, $to, $message) {
     29         $data = array('from' => $from, 'to' => $to, 'message' => $message, 'sent' => time()/*, 'recd' => 0*/);
     30         $value = json_encode($data);
     31         //生成json字符串
     32         $keyName = 'rec:' . $this -> getRecKeyName($from, $to);
     33         //echo $keyName;
     34         $res = $this -> redis -> lPush($keyName, $value);
     35         if (!$this -> checkUserReadable) {//消息接受者无法立刻查看时,将消息设置为未读
     36             $this -> cacheUnreadMsg($from, $to);
     37         }
     38         return $res;
     39     }
     40 
     41     /*
     42     * 获取聊天记录
     43     * @from 消息发送者id
     44     * @to 消息接受者id
     45     * @num 获取的数量
     46     *
     47     * 返回值,指定长度的包含聊天记录的数组
     48     */
     49     public function getChatRecord($from, $to, $num) {
     50         $keyName = 'rec:' . $this -> getRecKeyName($from, $to);
     51         //echo $keyName;
     52         $recList = $this -> redis -> lRange($keyName, 0, (int)($num));
     53         return $recList;
     54     }
     55 
     56     /*
     57     * 当用户上线时,或点开聊天框时,获取未读消息的数目
     58     * @user 用户id
     59     *
     60     * 返回值,一个所有当前用户未读的消息的发送者和数组
     61     * 数组格式为‘消息发送者id’=>‘未读消息数目’
     62     *
     63     */
     64     public function getUnreadMsgCount($user) {
     65         return $this -> redis -> hGetAll('unread_' . $user);
     66     }
     67 
     68     /*
     69     * 获取未读消息的内容
     70     * 通过未读消息数目,在列表中取得最新的相应消息即为未读
     71     * @from 消息发送者id
     72     * @to 消息接受者id
     73     *
     74     * 返回值,包括所有未读消息内容的数组
     75     *
     76     *
     77     */
     78     public function getUnreadMsg($from, $to) {
     79         $countArr = $this -> getUnreadMsgCount($to);
     80         $count = $countArr[$from];
     81         $keyName = 'rec:' . $this -> getRecKeyName($from, $to);
     82         return $this -> redis -> lRange($keyName, 0, (int)($count));
     83     }
     84 
     85     /*
     86     * 将消息设为已读
     87     * 当一个用户打开另一个用户的聊天框时,将所有未读消息设为已读
     88     * 清楚未读消息中的缓存
     89     * @from 消息发送者id
     90     * @to 消息接受者id
     91     *
     92     * 返回值,成功将未读消息设为已读则返回true,没有未读消息则返回false
     93     */
     94 
     95     public function setUnreadToRead($from, $to) {
     96         $res = $this -> redis -> hDel('unread_' . $to, $from);
     97         return (bool)$res;
     98     }
     99 
    100     /*
    101     * 当用户不在线时,或者当前没有立刻接收消息时,缓存未读消息,将未读消息的数目和发送者信息存到一个与接受者关联的hash数据中
    102     *
    103     * @from 发送消息的用户id
    104     * @to 接收消息的用户id
    105     *
    106     * 返回值,当前两个用户聊天中的未读消息
    107     *
    108     */
    109     private function cacheUnreadMsg($from, $to) {
    110         return $this -> redis -> hIncrBy('unread_' . $to, $from, 1);
    111     }
    112 
    113     /*生成聊天记录的键名,即按大小规则将两个数字排序
    114     * @from 消息发送者id
    115     * @to 消息接受者id
    116     *
    117     *
    118     */
    119     private function getRecKeyName($from, $to) {
    120         return ($from > $to) ? $to . '_' . $from : $from . '_' . $to;
    121     }
    122 
    123 }
    124 
    125 /*
    126 * 下面为测试用的代码 ,伪造数据模拟场景
    127 * 假定有两个用户id为2和3 ,2 向 3 发送消息
    128 *
    129 
    130 $chat = new chatClass();
    131 
    132 $chat -> checkUserReadable = true;
    133 for ($i = 0; $i < 20; $i++) {
    134 $chat -> setChatRecord('2', '3', 'message_' . $i);
    135 }
    136 
    137 echo 'get 20 chat records</br>';
    138 $arr = $chat -> getChatRecord('2', '3', 20);
    139 for ($j = 0; $j < count($arr); $j++) {
    140 echo $arr[$j] . '</br>';
    141 }
    142 
    143 $chat -> checkUserReadable = false;
    144 
    145 for ($m = 0; $m < 5; $m++) {
    146 $chat -> setChatRecord('2', '3', 'message_' . $m);
    147 }
    148 
    149 echo "</br>";
    150 $umsg_1 = $chat -> getUnreadMsgCount(3);
    151 echo "Unread message counts ";
    152 echo "</br>";
    153 print_r($umsg_1);
    154 echo "Unread message content </br> ";
    155 $umsgContent = $chat -> getUnreadMsg(2, 3);
    156 for ($n = 0; $n < count($umsgContent); $n++) {
    157 echo $arr[$n] . '</br>';
    158 }
    159 echo "</br>";
    160 $chat -> setUnreadToRead(2, 3);
    161 $umsg_2 = $chat -> getUnreadMsgCount(3);
    162 echo "</br>";
    163 echo "Unread message counts ";
    164 echo "</br>";
    165 print_r($umsg_2);
    166 *
    167 */
    168 ?>

    欢迎反馈交流

    如果本文章已帮助到您!

  • 相关阅读:
    flex
    导航守卫 -vue
    H5 History
    JSX -react
    插槽slot -vue
    js 模拟鼠标绘制方块
    js 模拟滚动条
    js 实现简易留言板功能
    js 实现端口列表话
    js 为数组编写该方法;indexOf
  • 原文地址:https://www.cnblogs.com/handle/p/9249967.html
Copyright © 2020-2023  润新知