<?php
namespace app\common\service;
use Workerman\Lib\Timer;
use GatewayWorker\Lib\Gateway;
use think\facade\Cache;
class Message
{
    public static function onWorkerStart($businessWorker)
    {
        echo "WorkerStart\n";
    }
    public static function onConnect($client_id)
    {
        // 连接到来后，定时30秒关闭这个链接，需要30秒内发认证并删除定时器阻止关闭连接的执行
        $_SESSION['auth_timer_id'] = Timer::add(30, function($client_id){
            Gateway::closeClient($client_id);
        }, [$client_id], false);
    }
    public static function onWebSocketConnect($client_id, $data)
    {
        // var_export($data);
    }
    /**
     * 有消息时触发该方法
     * @param int $client_id 发消息的client_id
     * @param mixed $message 消息
     * @return void
     */
    public static function onMessage($client_id, $message)
    {
        $Data = json_decode($message, true);
        p($Data);
        $AuthResult=self::authMessage($Data);
        if (!$AuthResult){
            Gateway::sendToCurrentClient(self::socketMsg('authFail'));
            Gateway::closeClient($client_id);
        }
        if ($AuthResult!==true)
            return Gateway::sendToCurrentClient($AuthResult);
        $uid=empty($Data['msg']['uid'])?0:$Data['msg']['uid'];
        switch($Data['type'])
        {
            case 'login':
                Timer::del($_SESSION['auth_timer_id']);
                $_SESSION['auth_timer_id']=null;
                $_SESSION['uid'] = $uid;
                Cache::set('MessageClientId::'.$client_id,$uid);
                Gateway::sendToCurrentClient(self::socketMsg('loginSuccess'));
                // 认证成功，删除 30关闭连接定 的时器
                break;
            case 'scanQrSuccess':
                if(empty($Data['msg']['client_id'])){
                    Gateway::sendToCurrentClient(self::socketMsg('sendScanQrFail',['err'=>'参数为空']));
                }else{
                    if(Gateway::isOnline($Data['msg']['client_id'])){
                        Gateway::sendToClient($Data['msg']['client_id'],self::socketMsg('scanQrSuccess'));
                        Gateway::sendToCurrentClient(self::socketMsg('sendScanQrSuccess'));
                    }else{
                        Gateway::sendToCurrentClient(self::socketMsg('sendScanQrFail',['err'=>'目标已离线']));
                    }
                }
                break;
            case 'qrloginSuccess':
                if(empty($Data['msg']['client_id'])){
                    Gateway::sendToCurrentClient(self::socketMsg('sendQrloginFail',['err'=>'参数为空']));
                }else{
                    if(Gateway::isOnline($Data['msg']['client_id'])){
                        Cache::set(md5($client_id.$Data['msg']['client_id']),[
                            'uid'=>$uid,
                            'ip'=>$Data['msg']['ip']
                        ],180);
                        Gateway::sendToClient($Data['msg']['client_id'],self::socketMsg('qrloginSuccess',['client_id'=>$Data['msg']['client_id']]));
                        Gateway::sendToCurrentClient(self::socketMsg('sendQrloginSuccess'));
                    }else{
                        Gateway::sendToCurrentClient(self::socketMsg('sendQrloginFail',['err'=>'目标已离线']));
                    }
                }
                break;
            case 'qrlogin':
                Timer::del($_SESSION['auth_timer_id']);
                $_SESSION['auth_timer_id']=null;
                Gateway::sendToCurrentClient(self::socketMsg('loginSuccess'));
                break;
        }
    }
    /**
     * 当用户断开连接时触发的方法
     * @param integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
    }
    public static function onWorkerStop($businessWorker)
    {
       echo "WorkerStop\n";
    }
    public static function authMessage($Data)
    {
        if (empty($Data['type']))
            return false;
        if ($Data['type']=='ping')
            return '{"type":"ping"}';
        if ($Data['type']=='qrlogin')
            return true;
        if ($Data['type']!=='login' && $_SESSION['auth_timer_id'])
            return self::socketMsg('notlogin');
        if (empty($Data['token']))
            return false;
        $MessageKey=Cache::get('Message::'.$Data['token']);
        if (empty($Data['msg']['uid']) 
            || $Data['msg']['uid']!==intval($MessageKey))
            return false;
        return true;
    }
    public static function socketMsg($type,$data=[])
    {
        $D=[
            'client_id' =>  $_SERVER['GATEWAY_CLIENT_ID'],
            'type'      =>  $type,
            'data'      =>  $data
        ];
        return json_encode($D);
    }
}