微信小程序+gatewayworker+php+tp框架开发,websocke即时通讯二

上一章讲了后台部署部分
https://blog.csdn.net/weixin_41987365/article/details/129047493?spm=1001.2014.3001.5502
这一回讲后端接口部分,直接贴代码了,相信大家都看得懂

<?php

namespace app\api\controller;

use app\api\enum\Communication;
use app\common\controller\Api;
use app\api\service\Token;
use app\Request;
use think\exception\HttpException;
use app\api\enum\User as UserEnum;
use app\api\model\User as UserModel;
use app\api\model\Communication as CommunicationModel;
use app\api\enum\Communication as CommunicationEnum;
use app\api\service\Token as TokenService;
use app\common\controller\JsonResult;

use think\cache\driver\Redis;
use think\facade\Cache;
use think\facade\Config;
use think\Controller;
// require_once '/vendor/GatewayWork/vendor/workerman/gateway-worker/src/Lib/Gateway.php';
// use GatewayWorker\Lib\Gateway;
use GatewayClient\Gateway;
// require_once __DIR__."/Protocols/GatewayProtocol.php";
// require_once __DIR__."/Lib/Gateway.php";

class Chat extends Controller
{
    /**
     * 根据用户id查询用户姓名
     */
    public function getIdName($uid){
        $res = UserModel::getIdName($uid);
        return $res;
    }

    /**
     * 根据用户id获取聊天双方头像信息
     */
    public function getHeadImg(){
        if (request()->isPost()){
            $res = UserModel::getHeadImg(input('post.'));
            return JsonResult::jsonSuccess($res,"ok",200);
        }
        throw new HttpException(404,"非法请求");
    }

    /**
     * 通过id获取单个用户昵称
     */
    public function getNickName(){
        if (request()->isPost()){
            $res = UserModel::getNickName(input('post.toid'));
            return JsonResult::jsonSuccess($res,"ok",200);
        }
        throw new HttpException(404,"非法请求");
    }

    /**
     * 通过聊天双方id获取聊天记录
     */
    public function messageLoad(){
        if (request()->isPost()){
            $res = CommunicationModel::messageLoad(input('post.'));
            return JsonResult::jsonSuccess($res,"ok",200);
        }
        throw new HttpException(404,"非法请求");
    }

    /**
     * 上传图片,返回图片地址
     */
    public function uploadImg(){
        if (request()->isPost()){
            //获取表单上传文件
            $file = request()->file('image');
            $suffix = substr(strrchr($file->getOriginalName(), "."), 1); // 文件后缀


            if(!in_array($suffix, config('upload.suffix_arr.image'))){
                throw new HttpException(404,"请上传格式为'".json(',',['jpg','jpeg','png','gif'])."'的文件");
            }

            if($file->getSize() > config('upload.size_arr.image')){ // 最大上传10M
                throw new HttpException(404,"上传的文件大小不能超过10M");
            }
            //上传文件到本地服务器
            $filename = \think\facade\Filesystem::disk('public')->putFile('', $file);

            if ($filename){
                // 上传成功 路径存入数据库
                $name = str_replace("\\","/",'/uploads/'.$filename);
                $data = [
                    'content' => config('upload.suffix_http').$name ,
                    'fromid' => input('fromid'),
                    'toid' => input('toid'),
                    'fromname' => $this->getIdName(input('fromid')),
                    'toname' => $this->getIdName(input('toid')),
                    'time' => time(),
//                    'isread' => input('online') == 1 ? Communication::read : Communication::uread,
                    'isread' => Communication::uread,
                    'type' => CommunicationEnum::image
                ];

                $insert = CommunicationModel::insert($data);
                if($insert){
                    return show(config('status.success'),"ok",['img_name'=>config('upload.suffix_http').$name],200);
                }
                throw new HttpException(404,"发送失败,图片路径保存失败!");
            }else{
                throw new HttpException(404,"文件上传失败");
            }
        }
        throw new HttpException(404,"非法请求");
    }

    /**
     * 根据uid获取当前用户聊天列表
     */
    public function getIdList(){
        if(request()->post()){
            // $token = request()->header('token');
            // TokenService::verifyToken($token);

            $res = CommunicationModel::getIdList(input('post.id'));
            $allNoRead = CommunicationModel::getCountAllNoRead(input('post.id'));
            $data=[
                'list'=>$res,
                'allNoRead'=>$allNoRead
            ];
            
            if (sizeof($res) > 0) {
                return JsonResult::jsonSuccess($data,"ok",200);
            } else {
                throw new HttpException(200, "当前没有对话列表");
            }
        }
        throw new HttpException(404,"非法请求");
    }

    /**
     * 通过消息id标记当前消息已读
     */
    public function isRead(){
        if(request()->post()){
            // $token = request()->header('token');
            // TokenService::verifyToken($token);

            $res = CommunicationModel::isRead(input('post.'));
            return JsonResult::jsonSuccess($res,"ok",200);;
            // if ($res > 0) {
            //     return show(config('status.success'), "ok", $res, 200);
            // } else {
            //     throw new HttpException(200, "标记已读失败");
            //}
        }
        throw new HttpException(404,"非法请求");
    }

    public function bind(){
        $message =input('post.');
        //客户端发送的数据
        // $message_data = json_decode($message);
        // if(!$message_data){
        //     return false;
        // }
        $client_id = $message['client_id'];
        $userId = $message['userid'];
        if(!$userId){
            return false;
        }
        // $cid  = Gateway::getClientIdByUid($userId);
        // if ($cid) return show('200','用户已经绑定',$cid);
        // 验证client_id合法性
        if (!Gateway::isOnline($client_id)) return JsonResult::jsonFailed('','client_id错误',400);
        // 验证当前客户端是否已经绑定
        $uid = Gateway::getUidByClientId($client_id);
        if ($uid) return JsonResult::jsonFailed($uid,'已经绑定',400);
        // 直接绑定
        Gateway::bindUid($client_id,$userId);
        // 返回成功
        return JsonResult::jsonSuccess(['type'=>'bind','status'=>true],"绑定成功",200);
    }
    public function send(){
        // 1. 验证数据是否合法
        // 2. 组织数据
        $message = input('post.');
        $data = $this->resdata($message);
        $to_id = $data['to_id'];
        $datas = [
            'fromid' => $message['fromid'],
            'fromname' => $this->getIdName($message['fromid']),
            'toid' => $message['toid'],
            'toname' => $this->getIdName($message['toid']),
            'content' => $message['data'],
            'time' => time(),
            'isread' => CommunicationEnum::uread,
            'type' => UserEnum::type
        ];
        // 3. 验证对方用户是否在线
        if (Gateway::isUidOnline($to_id)) {
            // 直接发送
            Gateway::sendToUid($to_id,json_encode($data));
            // 写入数据库
            CommunicationModel::add($datas);
            // 返回发送成功
            return JsonResult::jsonSuccess(['在线,发送成功'],'ok',200);
        }else{
            // 写入数据库
            CommunicationModel::add($datas);
            return JsonResult::jsonSuccess(['对方离线,发送成功'],'ok',200);
        }
         
        // else{
        //     // 不在线,写入消息队列
        //     // 获取之前消息
        //     // $redis = new Redis(Config::get('userchat_'.$to_id));
        //     $redis = new Redis(Config::get('cache.stores.redis'));
        //     $save_data = $redis->get('userchat_'.$to_id);
        //     if (!$save_data || !is_array($save_data)) $save_data = [];
        //     $save_data[] = $datas;
        //     // 写入数据库
        //     // 写入消息队列(含id)
        //     $redis->set('userchat_'.$to_id,$save_data);
        //     return show(400,'ok',$redis->get('userchat_'.$to_id));
        // }
        
    }

     // 组织数据
    public function resdata($request){
        return [
                'to_id'=>$request['toid'],
                'from_id'=>$request['fromid'],
                'data'=>$this->checkWords($request['data']),
                'user_pic'=> UserModel::getHeadOne($request['fromid']),
                'user_name'=>UserModel::getNickName($request['fromid']),
                'type'=>$request['type'],
                'time'=>time()
        ];
    }

}

而在events.php里,基本不做任何修改,只需要在连接成功时,返回client_id

class Events
{
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        // 向当前client_id发送数据 
        $data=[
         'type'=>'bind',
         'client_id'=>$client_id
        ];
        Gateway::sendToClient($client_id,json_encode($data));
    }
    
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message)
   {
        

   }
   
   /**
    * 当用户断开连接时触发
    * @param int $client_id 连接id
    */
   public static function onClose($client_id)
   {
       
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值