聊天室 php ChatApi

4 篇文章 0 订阅
2 篇文章 0 订阅

 thinkphp workerman 聊天室所需api:

ChatApi类说明:

聊天(用户,房间,好友,内容)的记录--已完成

聊天(用户,房间,好友,内容【可传递参数retention_data,保留$retentionData天的数据,其他的删除】)的删除--已完成

聊天(用户,房间,好友,内容【可传递参数retention_data,恢复$retentionData天的数据,其他的不恢复】)的恢复--已完成

<?php
/*
 * @Description: 
 * @ComposerRequire: 
 * @ComposerRemove: 
 * @Author: 阿海 <764882431@qq.com>
 * @Date: 2022-03-23 15:46:14
 * @LastEditTime: 2022-03-29 11:01:05
 * @LastEditors: 阿海
 */


namespace app\workerman\controller;

use think\Controller;
use think\Request;
use think\Db;

class ChatApi extends Controller
{
    //redis类
    private $redis;

    public function __construct(){
        $this->init();
    } 

    //redis的初始化
    private function init(){
        $config = config('redis.');
        $attr = [
            'db_id'=>$config['db_id'],
            'timeout'=>$config['timeout']
        ];
        $this->redis = app('redis',['config'=>$config,'attr'=>$attr])->getRedis();
    }

    /**
     * 返回随机头像
     */
    public function getAvatar($avatar = ''){
        if(empty($avatar)){
            $avatar = time();
        }
        return "https://api.multiavatar.com/".$avatar.".png";
    }
    

    /**
     * 随机创建用户---测试专用
     */
    public function getRandUserInfo(){
        $data['nickname'] = getName()['xm'];
        $data['description'] = getName()['description'];
        $id = $this->redis->hLen('chat_user_list');
        $data['create_time'] = time();
        $data['chat_no'] = $id ? rand_id($id+1,8) : rand_id(1,8);
        $data['headimgurl'] = "https://api.multiavatar.com/".$data['chat_no'].".png";
        $data['uuid'] = md5($data['chat_no'].time().rand(100,1000).rand(999,99999));
        if(isset($data['nickname'])){
            $data['letter'] = get_first_letter($data['nickname']);
        }

        //先写入用户信息
        $res = $this->writeUserRedis($data,$data['uuid']);

        if($res['code'] == 0){
            //给当前用户加上全部好友
            $list = $this->redis->hGetAll('chat_user_list');
            foreach ($list as $key => $value) {
                $bData = unserialize($value);
                if($data['uuid'] != $bData['uuid']){
                    $this->writeUserFriend($data['uuid'],$bData['uuid']);
                }
            }
        }

        return app('api_result')->toJson($res);
    }

    //生成房间号
    private function createRoomId($auuid = '',$buuid = ''){
        $arr = [$auuid,$buuid];
        sort($arr);
        $roomId = '';
        for($i=0;$i<count($arr);$i++){
            $roomId .= $arr[$i];
        }
        $roomId = md5($roomId);
        return $roomId;
    }

    //将两个用户绑定为好友
    public function writeUserFriend($auuid = '',$buuid = ''){

        if(empty($auuid) || empty($buuid)){
            return app('api_result')->returnArray(3,['msg'=>'缺少好友之间的ID!']);
        }

        $aData = unserialize($this->redis->hGet('chat_user_list',$auuid));
        $bData = unserialize($this->redis->hGet('chat_user_list',$buuid));

        if(!$aData || !$bData){
            return app('api_result')->returnArray(3,['msg'=>'相关的ID数据不在Redis中!']);
        }

        //生成初始的房间号,未进行md5
        $roomId = $this->createRoomId($auuid,$buuid);

        //将用户信息写入房间内
        $roomUserData = $this->redis->hGet('chat_room_id_user_list',$roomId);
        if(!$roomUserData){
            $roomUserData = [$aData,$bData];
            $this->redis->hSet('chat_room_id_user_list',$roomId,serialize($roomUserData));
        }

        //给A加上B好友
        $data = $this->redis->hGet('chat_user_friend_list',$auuid);
        if($data){
            $isFriend = false;
            $data = unserialize($data);
            //处理,判断是否已经是好友关系
            for($i=0;  $i<count($data);$i++){
                if($data[$i]['b_uuid'] == $buuid){
                    $isFriend = true;
                    break;
                }
            }
            if(!$isFriend){
                $data[] = [
                    'a_uuid'=>$auuid,
                    'b_uuid'=>$buuid,
                    'b_rename'=>$bData['nickname'],
                    'letter'=>get_first_letter($bData['nickname']),
                    'room_id'=>$roomId,
                    'create_time'=>time()
                ];
            }
        }else{
            $data = [[
                'a_uuid'=>$auuid,
                'b_uuid'=>$buuid,
                'b_rename'=>$bData['nickname'],
                'letter'=>get_first_letter($bData['nickname']),
                'room_id'=>$roomId,
                'create_time'=>time()
            ]];
        }
        $this->redis->hSet('chat_user_friend_list',$auuid,serialize($data));
        $this->writeChatRoomUserRedis($roomId,$auuid,1,0);

         //给B加上A好友
         $data = $this->redis->hGet('chat_user_friend_list',$buuid);
         if($data){
             $isFriend = false;
             $data = unserialize($data);
             //处理,判断是否已经是好友关系
             for($i=0;  $i<count($data);$i++){
                 if($data[$i]['b_uuid'] == $auuid){
                     $isFriend = true;
                     break;
                 }
             }
             if(!$isFriend){
                 $data[] = [
                     'a_uuid'=>$buuid,
                     'b_uuid'=>$auuid,
                     'b_rename'=>$aData['nickname'],
                     'letter'=>get_first_letter($aData['nickname']),
                     'room_id'=>$roomId,
                     'create_time'=>time()
                 ];
             }
         }else{
             $data = [[
                'a_uuid'=>$buuid,
                'b_uuid'=>$auuid,
                'b_rename'=>$aData['nickname'],
                'letter'=>get_first_letter($aData['nickname']),
                'room_id'=>$roomId,
                'create_time'=>time()
             ]];
         }
      
         $this->redis->hSet('chat_user_friend_list',$buuid,serialize($data));
         $this->writeChatRoomUserRedis($roomId,$buuid);
         
         return app('api_result')->returnArray(0,['msg'=>'已互成为好友']);
    }

    /**
     * 将用户写入到房间里面
     * @param $level = 用户的级别:0群成员,1.群管理员;2.群主
     * @param $roomLevel = 0青铜房间(限制加入人数为100人),1:白银房间(限制人数为300人),2:黄金房间(限制人数为500人),3铂金房间(限制人数1000),4钻石房间(不限制人数)
     */
    public function writeChatRoomUserRedis($roomId = '', $uuid = '', $level = 0, $roomLevel = 0){
        if(empty($roomId)){
            $roomId = input('get.room_id');
        }
        if(empty($roomId)){
            return app('api_result')->returnArray(3,['msg'=>'缺少房间号!']);
        }
        if(empty($uuid)){
            $uuid = input('get.uuid');
        }
        if(empty($uuid)){
            return app('api_result')->returnArray(3,['msg'=>'缺少用户ID!']);
        }
        $data = $this->redis->hGet('chat_room_user_list',$roomId);//房间是否存在
        if($data){
            $data = unserialize($data);
            $inRoom = false;
            for($i = 0; $i<count($data); $i++){
                $roomLevel = $data[$i]['room_level'];//当房间已经创建时,房间的等级不再变化,跟随已有用户的房间等级
                if($data[$i]['uuid'] == $uuid){
                    $inRoom = true;
                    break;
                }
            }
            if(!$inRoom){
                $data[] = [
                    'room_id'=>$roomId,
                    'uuid'=>$uuid,
                    'room_level'=>$roomLevel,
                    'level'=>$level,
                    'u_add_index'=>count($data)+1,
                    'create_time'=>time()
                ];
            }
        }else{
            $data = [[
                'room_id'=>$roomId,
                'uuid'=>$uuid,
                'room_level'=>$roomLevel,
                'level'=>$level,
                'u_add_index'=>1,
                'create_time'=>time()
            ]];
        }
        $data = serialize($data);
        $this->redis->hSet('chat_room_user_list',$roomId,$data);
        return app('api_result')->returnArray(0,['msg'=>'用户已加入房间','room_id'=>$roomId,'uuid'=>$uuid]);
    }

    //创建redis用户
    public function writeUserRedis($data = [],$uuid = ''){

        if(empty($data)){
            return app('api_result')->returnArray(3,['msg'=>'没有用户数据!']);
        }

        if(empty($uuid)){
            $uuid = isset($data['uuid']) ? $data['uuid'] : '';
        }

        if(empty($uuid)){
            return app('api_result')->returnArray(3,['msg'=>'缺少用户ID!']);
        }

        if(is_array($data)){
            $data = serialize($data);
        }
        $this->redis->hSet('chat_user_list',$uuid,$data);
        $data = unserialize($this->redis->hGet('chat_user_list',$uuid));
        if(!empty($data)){
            return app('api_result')->returnArray(0,['msg'=>'用户已在Redis中','data'=>$data]);
        }else{
            return app('api_result')->returnArray(3,['msg'=>'用户录入Redis失败!']);
        }
    }

    //获取全部用户
    public function getUserList(){
        $list = $this->redis->hGetAll('chat_user_list');
        $data = [];
        foreach ($list as $key => $value) {
           $data[] = unserialize($value);
        }
        return app('api_result')->echoJson(0,['msg'=>'redis中的全部用户','data'=>$data,'total'=>count($data)]);
    }

    //获取房间内的用户
    public function getRoomIdUserList($roomId = ''){
        if(empty($roomId)){
            $roomId = input('get.room_id');
        }
        if(empty($roomId)){
            return app('api_result')->echoJson(3,['msg'=>'缺少房间号!']);
        }
        $data = $this->redis->hGet('chat_room_id_user_list',$roomId);
        if(!$data){
            return app('api_result')->echoJson(0,['msg'=>'当前房间没有任何用户']);
        }
        $data = unserialize($data);
        return app('api_result')->echoJson(0,['msg'=>'当前房间中的全部用户','data'=>$data,'total'=>count($data)]);
    }

    //获取单个用户的个人信息
    public function getUserInfo2Array($uuid = ''){
        try {
            if(empty($uuid)){
                $uuid = input('get.uuid');
            }
            if(empty($uuid)){
                return app('api_result')->returnArray(3,['msg'=>'缺少用户ID!']);
            }
            $data = $this->redis->hGet('chat_user_list',$uuid);
            if($data){
                return app('api_result')->returnArray(0,['data'=>unserialize($data),'msg'=>'请求成功']);
            }
            return app('api_result')->returnArray(3,['msg'=>'用户ID不存在!']);
        } catch (\Exception $e) {
            return app('api_result')->returnArray(3,['msg'=>"文件:" . $e->getFile() .";代码不可执行,错误行:".$e->getLine().";错误信息:".$e->getMessage()]);
        }
    }

    //获取单个用户的个人信息
    public function getUserInfo($uuid = ''){
       return app('api_result')->toJson($this->getUserInfo2Array($uuid));
    }

    //获取好友的信息 包含备注
    public function getFriendUserInfo($auuid = '', $buuid = ''){
        if(empty($auuid)){
            $auuid = input('get.a_uuid');
        }
        if(empty($buuid)){
            $buuid = input('get.b_uuid');
        }
        if(empty($auuid) || empty($buuid)){
            return app('api_result')->echoJson(3,['msg'=>'缺少用户ID!']);
        }
        // $data = $this->redis->hGet('chat_user_list',$auuid);
        $aFriendData = $this->redis->hGet('chat_user_friend_list',$auuid);
        if($aFriendData){
            $aFriendData = unserialize($aFriendData);
            $bData = $this->redis->hGet('chat_user_list',$buuid);
            $bData = unserialize($bData);
            $data = $bData;
            
            for($i = 0; $i<count($aFriendData); $i++){
                if($aFriendData[$i]['b_uuid'] == $buuid){
                    $data['b_rename']= $aFriendData[$i]['b_rename'];
                    $data['room_id']= $aFriendData[$i]['room_id'];
                    $data['create_time']= $aFriendData[$i]['create_time'];
                    $data['b_uuid']= $aFriendData[$i]['b_uuid'];
                    $data['friend_info'] =  $bData;
                    break;
                }
            }
            return app('api_result')->echoJson(0,['data'=>$data,'msg'=>'请求成功']);
        }
        return app('api_result')->echoJson(3,['msg'=>'用户ID不存在!']);
    }

    //获取这个房间的聊天内容
    public function getRoomIdChatList($roomId = '', $page = 1, $pageSize = 15){
        if(empty($roomId)){
            $roomId = input('get.room_id');
        }
        if(empty($roomId)){
            return app('api_result')->echoJson(3,['msg'=>'缺少房间ID!']);
        }

        $data = $this->redis->hGet('chat_room_id_chat_list',$roomId);
        if(!$data){
            return app('api_result')->echoJson(0,['msg'=>'请求成功','data'=>['list'=>[],'count'=>0],'page'=>$page,'pageSize'=>$pageSize,'total'=>0]);
        }
     
        $data = array_reverse(unserialize($data)); //逆序数据
        $start= ($page-1)*$pageSize;//偏移量,当前页-1乘以每页显示条数
        $total = count($data);
        $data = array_slice($data,$start,$pageSize);
        $chatData = [];
        for($i = 0; $i<count($data); $i++){
            if(!(isset($data[$i]['system_type']) && $data[$i]['system_type'] == 'login')){
                $chatData[] = array_merge($data[$i],[
                    'view_index'=>  $total - $start*count($data) + $i + 1,
                    'userinfo'=>$data[$i]['user_info'],
                    'time'=>$data[$i]['show_date'],
                    'msg'=>[
                        'view_index'=>$total - $start*count($data) + $i + 1,
                        'time'=>date("Y/m/d H:i:s",$data[$i]['show_date']),
                        'type'=>!empty($data[$i]['system_type'])?$data[$i]['system_type']:$data[$i]['msg_type'],
                        'content'=>json_decode($data[$i]['content'],true),
                        'userinfo'=>json_decode($data[$i]['user_info'],true)
                    ]
                ]);
            }
           
        }
     
        $clear = false;
        if($page == 1 && input('?get.uuid')){
            $this->writeChatUnreadRedis($roomId , input('get.uuid'), true);
            $clear = true;
        }

        return app('api_result')->echoJson(0,['msg'=>'请求成功','data'=>['list'=>$chatData,'count'=>count($chatData)],'page'=>$page,'pageSize'=>$pageSize,'total'=>$total,'clear_unread'=>$clear]);
  
    }
    
    //清空当前用户的未读数
    public function clearUnread($roomId = '', $uuid = ''){
        if(empty($roomId)){
           $roomId = input('post.room_id');
        }
        if(empty($uuid)){
            $uuid = input('post.uuid');
        }
        return app('api_result')->toJson($this->writeChatUnreadRedis($roomId,$uuid,true));
    }

    //写入用户在这个房间的未读数
    public function writeChatUnreadRedis($roomId = '', $uuid = '', $isClearUnread = false){
        try {
            if(empty($roomId)){
                return app('api_result')->returnArray(3,['msg'=>'缺少房间ID!']);
            }
            if(empty($uuid)){
                return app('api_result')->returnArray(3,['msg'=>'缺少用户ID!']);
            }
            $key = md5($roomId.$uuid);
    
            if($isClearUnread){
                $this->redis->hSet('chat_room_id_chat_unread',$key,0);
                return app('api_result')->returnArray(0,['msg'=>'当前用户的未读数已清空']);
            }
    
            $data = $this->redis->hGet('chat_room_id_chat_unread',$key);
            if(!$data){
                $this->redis->hSet('chat_room_id_chat_unread',$key,1);
                return app('api_result')->returnArray(0,['msg'=>'当前用户的未读数为:1条']);
            }
            $data += 1;
            $this->redis->hSet('chat_room_id_chat_unread',$key,$data);
            return app('api_result')->returnArray(0,['msg'=>'当前用户的未读数为:'.$data.'条']);
        } catch (\Exception $e) {
            return app('api_result')->returnArray(3,['msg'=>"文件:" . $e->getFile() .";代码不可执行,错误行:".$e->getLine().";错误信息:".$e->getMessage()]);
        }
    }

    //记录聊天内容
    public function writeChatRedis($data = [], $roomId = ''){
        try {
            if(empty($data)){
                return app('api_result')->returnArray(3,['msg'=>'没有聊天数据!']);
            }
            if(empty($roomId)){
                return app('api_result')->returnArray(3,['msg'=>'缺少房间ID!']);
            }
            $historyData = $this->redis->hGet('chat_room_id_chat_list',$roomId);
            $historyData = $historyData?unserialize($historyData):[];
            $historyData[] = $data; 
            $this->redis->hSet('chat_room_id_chat_list',$roomId,serialize($historyData));
            return app('api_result')->returnArray(0,['msg'=>'聊天内容已记录']);
        } catch (\Exception $e) {
            return app('api_result')->returnArray(3,['msg'=>"文件:" . $e->getFile() .";代码不可执行,错误行:".$e->getLine().";错误信息:".$e->getMessage()]);
        }
    }

    //获取好友列表--通讯录使用
    public function getUserFriendList($uuid = ''){
        if(empty($uuid)){
            $uuid = input('get.uuid');
        }

        if(empty($uuid)){
            return app('api_result')->echoJson(3,['msg'=>'缺少用户ID!']);
        }

        $data = $this->redis->hGet('chat_user_list',$uuid);
        if(!$data){
            return app('api_result')->echoJson(3,['msg'=>'用户不存在Redis中!']);
        }

        $data = $this->redis->hGet('chat_user_friend_list',$uuid);
        if($data){
            $data = unserialize($data);
            for($i=0; $i<count($data); $i++){
                $key = md5($data[$i]['room_id'].$uuid);
                $unread = $this->redis->hGet('chat_room_id_chat_unread',$key);
                $data[$i]['unread'] = $unread ? $unread : 0;

                $data[$i]['uuid'] = $data[$i]['b_uuid'];
                $bData = $this->redis->hGet('chat_user_list',$data[$i]['uuid']);
                $bData = $bData?unserialize($bData):false;
                $data[$i]['headimgurl'] = $bData ? $bData['headimgurl'] : '';
                $data[$i]['description'] = $bData ? $bData['description'] : '';
                $data[$i]['nickname'] = $bData ? $bData['nickname'] : '';
            }
         
            return app('api_result')->echoJson(0, ['list'=>$data,'letter_list'=>split_by_letter($data),'count'=>count($data)]);
        }
       
        return app('api_result')->echoJson(0,['msg'=>'用户没有好友']);
    }

    //特别接口-- 获取好友列表 --主页使用-- 包含未读数,最后一条信息
    public function getChatUserFriendList($uuid = ''){
   
        if(empty($uuid)){
            $uuid = input('get.uuid');
        }

        if(empty($uuid)){
            return app('api_result')->echoJson(3,['msg'=>'缺少用户ID!']);
        }

        $data = $this->redis->hGet('chat_user_list',$uuid);
        if(!$data){
            return app('api_result')->echoJson(3,['msg'=>'用户不存在Redis中!']);
        }

        $data = $this->redis->hGet('chat_user_friend_list',$uuid);
        if($data){
            $data = unserialize($data);
            // return app('api_result')->echoJson(0,['data'=>$data]);
            $friendList = [];
            for($i=0; $i<count($data); $i++){
                $key = md5($data[$i]['room_id'].$uuid);//这里的uuid是用户自己的uuid
                $unread = $this->redis->hGet('chat_room_id_chat_unread',$key);
                $chatData = $this->redis->hGet('chat_room_id_chat_list',$data[$i]['room_id']);
                $chatData = $chatData ? unserialize($chatData) : [];
                // $lastMsgData  = empty($chatData) ? [] : array_pop($chatData);
                $lastMsgData = []; //最后一条记录不是登录信息的聊天内容
                if($chatData){
                    $chatData = array_reverse($chatData);
                    for($j=0; $j<count($chatData); $j++){
                        if(!(isset($chatData[$j]['system_type']) && $chatData[$j]['system_type'] == 'login')){
                            $lastMsgData = $chatData[$j];
                            break;
                        }
                    }
                }

                $lastMsg = empty($lastMsgData) ? ['text'=>''] : json_decode($lastMsgData['content'],true);
                $lastTime = empty($lastMsgData) ? $data[$i]['create_time']*1000 : $lastMsgData['show_date']*1000; //js 是13位
                $friendData = $this->redis->hGet('chat_user_list',$data[$i]['b_uuid']);//好友的uuid==
                $friendData =  $friendData ? unserialize($friendData) : [];
                $friendData['b_rename'] = $data[$i]['b_rename'];
                $friendData['letter'] = $data[$i]['letter'];
                $friendList[$uuid.'_'.$data[$i]['room_id']] = [
                    'unread_num'=>$unread ? $unread : 0,
                    'user_headimgurls'=>[],//群组图片集==目前没有使用
                    'last_msg'=>$lastMsg,
                    'friend_info'=>$friendData,
                    'room_id'=>$data[$i]['room_id'],
                    'time'=> $lastTime
                ];
            }
         
            return app('api_result')->echoJson(0,['data'=>array_sort($friendList,'time',SORT_DESC)]);
        }

        return app('api_result')->echoJson(0,['msg'=>'用户没有好友']);
            
    }

    // 访问 check_chat_api  --- 所有的恢复接口之前,应该将数据写入到数据库中再进行恢复
    public function checkChatApi(){
        if(input('?get.type')){
            switch (input('get.type')) {
                case 'write_chat':
                    //将聊天内容写入数据库
                    return app('api_result')->toJson($this->writeChat());//--成功--success
                    break;
                case 'write_chat_user':
                    //将用户数据写入数据库
                    return app('api_result')->toJson($this->writeChatUser());//--成功--success
                    break;
                    //将用户的好友关系写入数据库
                case 'write_chat_user_friend':
                    return app('api_result')->toJson($this->writeChatUserFriend());//--成功--success
                    break;
                case 'write_chat_user_room':
                    //将用户的群组房间关系记录入数据库
                    return app('api_result')->toJson($this->writeChatUserRoom());//--成功--success 
                    break;
                case 'del_chat':
                    //将聊天内容 清空redis  只保留最近30天
                    if(input('?get.retention_data') && input('get.retention_data')>0){
                        return app('api_result')->toJson($this->delChatRedis(input('get.retention_data')));//--成功--success
                    }
                    return app('api_result')->toJson($this->delChatRedis());//--成功--success
                    break;
                case 'del_chat_user':
                    //将用户数据 清空redis
                    return app('api_result')->toJson($this->delChatUserRedis());//--成功--success
                    break;
                    //将用户的好友关系 清空redis
                case 'del_chat_user_friend':
                    return app('api_result')->toJson($this->delChatUserFriendRedis());//--成功--success
                    break;
                case 'del_chat_user_room':
                    //将用户的群组房间关系 清空redis
                    return app('api_result')->toJson($this->delChatUserRoomRedis());//--成功--success 
                    break;
                case 'recover_chat':
                    // $this->writeChat();//-在这里--不生效--异步的问题- 所以最好先单独执行
                    //将聊天内容 恢复到redis中 只保留最近30天
                    if(input('?get.retention_data') && input('get.retention_data')>0){
                        return app('api_result')->toJson($this->recoverChatRedis(input('get.retention_data')));//--成功--success
                    }
                    return app('api_result')->toJson($this->recoverChatRedis());//--成功--success
                    break;
                case 'recover_chat_user':
                    // $this->writeChatUser();//-在这里--不生效--异步的问题- 所以最好先单独执行
                    //将用户数据 恢复到redis中
                    return app('api_result')->toJson($this->recoverChatUserRedis());//--成功--success
                    break;
                case 'recover_chat_user_friend':
                    // $this->writeChatUserFriend();//-在这里--不生效--异步的问题- 所以最好先单独执行
                      //将用户的好友关系 恢复到redis中
                    return app('api_result')->toJson($this->recoverChatUserFriendRedis());//--成功--success
                    break;
                case 'recover_chat_user_room':
                    // $this->writeChatUserRoom();//-在这里--不生效--异步的问题- 所以最好先单独执行
                    //将用户的群组房间关系 恢复到redis中
                    return app('api_result')->toJson($this->recoverChatUserRoomRedis());//--成功--success 
                    break;        
                default:
                    return app('api_result')->echoJson(3,['msg'=>'未定义类型']);
                    break;
            }
        }
        return app('api_result')->echoJson(3,['msg'=>'缺少参数类型']);
    }

    //将聊天内容-写入数据库
    public function writeChat(){
        $data = $this->redis->hGetAll('chat_room_id_chat_list');
        $list = Db::name('chat')->where('delete_time',0)->order('create_time desc')->find();
        $chatData = [];
        if($data){
            //针对用户进行批量写入
            foreach($data as $key => $value){
                $roomData = unserialize($value);//当前房间的全部聊天内容
                $roomDatas = []; // 新写入的数据
                //过滤小于数据里面已经成功的数据
                if($list){
                    //非首次写入数据
                    for($i = 0; $i < count($roomData); $i++){
                        $isIn = false;
                        //如果小于最后数据的全部过滤
                        if($list['create_time'] > $roomData[$i]['create_time']){
                            $isIn = true;
                        }else{
                             //当前批次最后同一时间的相同数据进行过滤
                            $lists = Db::name('chat')->where([['delete_time','eq',0],['create_time','eq',$list['create_time']]])->select();
                            if($list['create_time'] == $roomData[$i]['create_time']){
                                for($j = 0; $j<count($lists); $j++){
                                    if($roomData[$i]['create_time'] == $lists[$j]['create_time'] && $roomData[$i]['from_id'] == $lists[$j]['from_id'] && $roomData[$i]['to_id'] == $lists[$j]['to_id'] && $roomData[$i]['content'] == $lists[$j]['content'] ){
                                        $isIn = true;
                                    }
                                }
                            }
                        }
                        if(!$isIn){
                            $roomDatas[] = $roomData[$i];
                        }
                    }
                }else{
                  
                    //如果数据库没有任何数据- 首次写入 == 全部写入
                    for($i = 0; $i < count($roomData); $i++){
                        $roomDatas[] = $roomData[$i];
                    }
                }
              
                $chatData = array_merge($chatData,$roomDatas);
            }

        }
        
        if(!empty($chatData)){
            $insertRes = model('Chat')->insertAll($chatData);
        }

        return app('api_result')->returnArray(0,['msg'=>'聊天内容已写入数据库','data'=>$chatData,'total'=>count($chatData)]);
    }

    //将数据库中的聊天恢复至redis中
    public function recoverChatRedis($retentionData = 30){
        $data = $this->redis->hGetAll('chat_room_id_chat_list');
        $num = 0;
        foreach($data as $key => $value){
            $where = [['delete_time','eq',0],['room_id','eq',$key],['create_time','>',time()-$retentionData*24*60*60]];
            $list = Db::name('chat')->where($where)->field('id,delete_time,update_time',true)->order('create_time asc')->select();
            if(count($list)>0){
                $num++;
                $this->redis->hSet('chat_room_id_chat_list',$key,serialize($list));
            }
        }
        return app('api_result')->returnArray(0,['msg'=>'聊天内容已恢复到redis中','total'=>$num]);
    }
    
    //将用户数据-写入数据库
    public function writeChatUser(){
        $list = $this->redis->hGetAll('chat_user_list');
        $data = [];
        foreach ($list as $key => $value) {
           $data[] = unserialize($value);
        }
        $users = Db::name('chat_user')->where('delete_time',0)->select();
        $updateAll = [];
        $insertAll = [];
        for($i = 0; $i<count($data); $i++){
            $inDb = false;
            for($j = 0; $j<count($users); $j++){
                if($users[$j]['uuid'] == $data[$i]['uuid']){
                    $inDb = true;
                    $updateAll[] = [
                        'id'=>$users[$j]['id'],
                        'wx_openid'=>isset($data[$i]['wx_openid'])?$data[$i]['wx_openid']:$users[$j]['wx_openid'],
                        'mini_openid'=>isset($data[$i]['mini_openid'])?$data[$i]['mini_openid']:$users[$j]['mini_openid'],
                        'letter'=>isset($data[$i]['letter'])?$data[$i]['letter']:$users[$j]['letter'],
                        'chat_no'=>isset($data[$i]['chat_no'])?$data[$i]['chat_no']:$users[$j]['chat_no'],
                        'nickname'=>isset($data[$i]['nickname'])?$data[$i]['nickname']:$users[$j]['nickname'],
                        'description'=>isset($data[$i]['description'])?$data[$i]['description']:$users[$j]['description'],
                        'user_name'=>isset($data[$i]['user_name'])?$data[$i]['user_name']:$users[$j]['user_name'],
                        'user_tel'=>isset($data[$i]['user_tel'])?$data[$i]['user_tel']:$users[$j]['user_tel'],
                        'user_pwd'=>isset($data[$i]['user_pwd'])?$data[$i]['user_pwd']:$users[$j]['user_pwd'],
                        'headimgurl'=>isset($data[$i]['headimgurl'])?$data[$i]['headimgurl']:$users[$j]['headimgurl'],
                        'status'=>isset($data[$i]['status'])?$data[$i]['status']:$users[$j]['status'],
                        'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:$users[$j]['create_time'],
                        'update_time'=>time()
                    ];
                    break;
                }
            }
            if(!$inDb){
                $insertAll[] = [
                    'wx_openid'=>isset($data[$i]['wx_openid'])?$data[$i]['wx_openid']:'',
                    'mini_openid'=>isset($data[$i]['mini_openid'])?$data[$i]['mini_openid']:'',
                    'letter'=>isset($data[$i]['letter'])?$data[$i]['letter']:'',
                    'uuid'=>isset($data[$i]['uuid'])?$data[$i]['uuid']:'',
                    'chat_no'=>isset($data[$i]['chat_no'])?$data[$i]['chat_no']:'',
                    'nickname'=>isset($data[$i]['nickname'])?$data[$i]['nickname']:'',
                    'description'=>isset($data[$i]['description'])?$data[$i]['description']:'',
                    'user_name'=>isset($data[$i]['user_name'])?$data[$i]['user_name']:'',
                    'user_tel'=>isset($data[$i]['user_tel'])?$data[$i]['user_tel']:'',
                    'user_pwd'=>isset($data[$i]['user_pwd'])?$data[$i]['user_pwd']:'',
                    'headimgurl'=>isset($data[$i]['headimgurl'])?$data[$i]['headimgurl']:'',
                    'status'=>isset($data[$i]['status'])?$data[$i]['status']:1,
                    'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:time(),
                ];
            }
        }

        if(!empty($updateAll)){
            $updateRes = model('ChatUser')->saveAll($updateAll);
        }

        if(!empty($insertAll)){
            $insertRes = model('ChatUser')->insertAll($insertAll);
        }

        return app('api_result')->returnArray(0,['msg'=>'redis中的全部用户','update_all'=>$updateAll,'insert_all'=>$insertAll,'total'=>count($data)]);
    }

    //将数据库中的数据恢复至redis中
    public function recoverChatUserRedis(){
        $users = Db::name('chat_user')->where('delete_time',0)->field('id,delete_time,update_time',true)->order('id asc')->select();
        $num = 0;
        for($i = 0 ; $i< count($users); $i++){
            $num++;
            $this->redis->hSet('chat_user_list',$users[$i]['uuid'],serialize($users[$i]));
        }
        return app('api_result')->returnArray(0,['msg'=>'数据库中的全部用户已恢复至redis中','total'=>$num]);
    }

    //将用户的好友关系写入数据库
    public function writeChatUserFriend(){
        $list = $this->redis->hGetAll('chat_user_friend_list');
        $usersFriend = Db::name('chat_user_friend')->where('delete_time',0)->select();
        $updateAll = [];
        $insertAll = [];

        foreach ($list as $key => $value) {
            $data = unserialize($value);
            for($i = 0; $i < count($data); $i++){
                $inDb = false;
                for($j = 0; $j<count($usersFriend); $j++){
                    if($usersFriend[$j]['a_uuid'] == $key && $usersFriend[$j]['b_uuid'] == $data[$i]['b_uuid']){
                        $inDb = true;
                        $updateAll[] = [
                            'id'=>$usersFriend[$j]['id'],
                            'a_uuid'=>isset($data[$i]['a_uuid'])?$data[$i]['a_uuid']:$usersFriend[$j]['a_uuid'],
                            'b_uuid'=>isset($data[$i]['b_uuid'])?$data[$i]['b_uuid']:$usersFriend[$j]['b_uuid'],
                            'b_rename'=>isset($data[$i]['b_rename'])?$data[$i]['b_rename']:$usersFriend[$j]['b_rename'],
                            'letter'=>isset($data[$i]['letter'])?$data[$i]['letter']:$usersFriend[$j]['letter'],
                            'room_id'=>isset($data[$i]['room_id'])?$data[$i]['room_id']:$usersFriend[$j]['room_id'],
                            'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:$usersFriend[$j]['create_time'],
                            'update_time'=>time()
                        ];
                        break;
                    }
                }
                if(!$inDb){
                    $insertAll[] = [
                        'a_uuid'=>isset($data[$i]['a_uuid'])?$data[$i]['a_uuid']:'',
                        'b_uuid'=>isset($data[$i]['b_uuid'])?$data[$i]['b_uuid']:'',
                        'b_rename'=>isset($data[$i]['b_rename'])?$data[$i]['b_rename']:'',
                        'letter'=>isset($data[$i]['letter'])?$data[$i]['letter']:'',
                        'room_id'=>isset($data[$i]['room_id'])?$data[$i]['room_id']:'',
                        'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:time(),
                    ];
                }
            }
         }

        if(!empty($updateAll)){
            $updateRes = model('ChatUserFriend')->saveAll($updateAll);
        }

        if(!empty($insertAll)){
            $insertRes = model('ChatUserFriend')->insertAll($insertAll);
        }

        return app('api_result')->returnArray(0,['msg'=>'redis中的全部好友关系','update_all'=>$updateAll,'insert_all'=>$insertAll,'total'=>count($updateAll)+count($insertAll)]);
    }

    //将数据库中好友关系恢复至redis中
    public function recoverChatUserFriendRedis(){
        $usersFriend = Db::name('chat_user_friend')->where('delete_time',0)->field('id,delete_time,update_time',true)->order('id asc')->select();
        $data = [];
        for($i = 0 ; $i< count($usersFriend); $i++){
            if(!isset($data[$usersFriend[$i]['a_uuid']])){
                $data[$usersFriend[$i]['a_uuid']]= [$usersFriend[$i]];
            }else{
                $data[$usersFriend[$i]['a_uuid']][] = $usersFriend[$i];
            }
        }
        $num = 0;
        foreach ($data as $key => $value) {
            $num++;
            $list = $this->redis->hSet('chat_user_friend_list',$key,serialize($value));
        }
        return app('api_result')->returnArray(0,['msg'=>'数据库中的全部好友关系已恢复至redis中','total'=>$num]);
    }

    //将用户的黑名单写入数据库--- 目前没有使用到
    public function writeChatUserBlacklist(){

    }

    //将用户的群组房间关系记录入数据库
    public function writeChatUserRoom(){
        $list = $this->redis->hGetAll('chat_room_user_list');
        $users = Db::name('chat_room_user')->where('delete_time',0)->select();
        $updateAll = [];
        $insertAll = [];

        foreach ($list as $key => $value) {
            $data = unserialize($value);
            for($i = 0; $i < count($data); $i++){
                $inDb = false;
                for($j = 0; $j<count($users); $j++){
                    if($users[$j]['room_id'] == $key && $users[$j]['uuid'] == $data[$i]['uuid']){
                        $inDb = true;
                        $updateAll[] = [
                            'id'=>$users[$j]['id'],
                            'room_id'=>isset($data[$i]['room_id'])?$data[$i]['room_id']:$users[$j]['room_id'],
                            'uuid'=>isset($data[$i]['uuid'])?$data[$i]['uuid']:$users[$j]['uuid'],
                            'u_level'=>isset($data[$i]['u_level'])?$data[$i]['u_level']:$users[$j]['u_level'],
                            'u_add_index'=>isset($data[$i]['u_add_index'])?$data[$i]['u_add_index']:$users[$j]['u_add_index'],
                            'room_level'=>isset($data[$i]['room_level'])?$data[$i]['room_level']:$users[$j]['room_level'],
                            'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:$users[$j]['create_time'],
                            'update_time'=>time()
                        ];
                        break;
                    }
                }
                if(!$inDb){
                    $insertAll[] = [
                        'room_id'=>isset($data[$i]['room_id'])?$data[$i]['room_id']:'',
                        'uuid'=>isset($data[$i]['uuid'])?$data[$i]['uuid']:'',
                        'u_level'=>isset($data[$i]['u_level'])?$data[$i]['u_level']:0,
                        'u_add_index'=>isset($data[$i]['u_add_index'])?$data[$i]['u_add_index']:count($data)+1,
                        'room_level'=>isset($data[$i]['room_level'])?$data[$i]['room_level']:'',
                        'create_time'=>isset($data[$i]['create_time'])?$data[$i]['create_time']:time(),
                    ];
                }
            }
         }

        if(!empty($updateAll)){
            $updateRes = model('ChatRoomUser')->saveAll($updateAll);
        }

        if(!empty($insertAll)){
            $insertRes = model('ChatRoomUser')->insertAll($insertAll);
        }

        return app('api_result')->returnArray(0,['msg'=>'redis中各个房间内的所有用户','update_all'=>$updateAll,'insert_all'=>$insertAll,'total'=>count($updateAll)+count($insertAll)]);
    }

    //将数据库中的群组关系恢复至redis中
    public function recoverChatUserRoomRedis(){
        $userRoom = Db::name('chat_room_user')->where('delete_time',0)->field('id,delete_time,update_time',true)->order('id asc')->select();
        $data = [];
        for($i = 0 ; $i< count($userRoom); $i++){
            if(!isset($data[$userRoom[$i]['room_id']])){
                $data[$userRoom[$i]['room_id']]= [$userRoom[$i]];
            }else{
                $data[$userRoom[$i]['room_id']][] = $userRoom[$i];
            }
        }
        $num = 0;
        foreach ($data as $key => $value) {
            $num++;
            $list = $this->redis->hSet('chat_room_user_list',$key,serialize($value));
        }
        return app('api_result')->returnArray(0,['msg'=>'数据库中的全部群组关系已恢复至redis中','total'=>$num]);
    }
    
    //清空redis的聊天数据--只保留最近30天
    public function delChatRedis($retentionData = 30){
        $list = $this->redis->hGetAll('chat_room_id_chat_list');
        
        $num = 0;
        if($list){
            //针对用户进行批量写入
            foreach($list as $key => $value){
                $roomData = [];
                $data = unserialize($value);//当前房间的全部聊天内容
                for($i=0; $i<count($data); $i++){
                    if($data[$i]['create_time'] > (time()-$retentionData*24*60*60)){
                        $roomData[] = $data[$i]; 
                        $num++;
                    }
                }
                $this->redis->hSet('chat_room_id_chat_list',$key,serialize($roomData));
            }
        }
     
        return app('api_result')->returnArray(0,['msg'=>'聊天内容只保留最近'.$retentionData.'天的数据','total'=>$num]);
    }

    //清空redis的用户数据
    public function delChatUserRedis(){
        $list = $this->redis->hGetAll('chat_user_list');
        if($list){
            foreach ($list as $key => $value) {
                $this->redis->hDel('chat_user_list',$key);
            }
        }
        return app('api_result')->returnArray(0,['msg'=>'redis中的全部用户已删除']);
    }

    //清空redis的用户的好友数据
    public function delChatUserFriendRedis(){
        $list = $this->redis->hGetAll('chat_user_friend_list');
        if($list){
            foreach ($list as $key => $value) {
                $this->redis->hDel('chat_user_friend_list',$key);
            }
        }
        return app('api_result')->returnArray(0,['msg'=>'redis中的全部好友关系已删除']);
    }

    //清空redis的用户的黑名单数据
    public function delChatUserBlacklistRedis(){
        
    }

    //清空redis的用户的群组房间关系
    public function delChatUserRoomRedis(){
        $list = $this->redis->hGetAll('chat_room_user_list');
        if($list){
            foreach ($list as $key => $value) {
                $this->redis->hDel('chat_room_user_list',$key);
            }
        }
        return app('api_result')->returnArray(0,['msg'=>'redis中的全部群组房间关系已删除']);
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHP WebSocket 聊天室是一种基于 WebSocket 协议的实时通信系统,它允许多个用户在一个聊天室中实时交流。下面是一个简单的介绍: 1. WebSocket 协议:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,它允许服务器主动向客户端推送数据,而不需要客户端发起请求。相比传统的 HTTP 请求-响应模式,WebSocket 提供了更低的延迟和更高的实时性。 2. PHP WebSocket 库:PHP 并不原生支持 WebSocket 协议,但可以使用第三方库来实现 WebSocket 功能。其中比较常用的库有 Ratchet、Swoole 等。这些库提供了简单易用的接口,帮助开发者快速构建 WebSocket 服务器。 3. 聊天室功能:PHP WebSocket 聊天室通常具备以下功能: - 用户注册和登录:用户可以通过注册和登录来进入聊天室。 - 实时消息发送和接收:用户可以发送消息到聊天室,并实时接收其他用户发送的消息。 - 在线用户列表:显示当前在线的用户列表,方便用户选择私聊对象。 - 私聊功能:用户可以选择某个在线用户进行私聊。 - 表情和文件发送:支持发送表情和文件等附件。 4. 实现步骤: - 创建 WebSocket 服务器:使用 PHP WebSocket 库创建一个 WebSocket 服务器,监听指定的端口。 - 处理连接和消息:当客户端连接到服务器时,建立 WebSocket 连接,并处理客户端发送的消息。 - 广播消息:将接收到的消息广播给所有在线用户,实现实时通信效果。 - 私聊功能:根据用户选择的私聊对象,将消息发送给指定的用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值