<?php

namespace app\index\logic\events;

use app\api\controller\BaseWssApi;
use app\api\logic\PartnerOfflineLogic;
use app\api\logic\UserLogic;
use app\api\logic\WssMessageLogic;
use app\index\logic\Baselogic;
use GatewayWorker\Lib\Gateway;
use think\Db;
use think\worker\Application;
use wanghua\general_utility_tools_php\http\Curl;
use wanghua\general_utility_tools_php\tool\Tools;
use Workerman\Worker;

/**
 * 本事件监控逻辑
 *
 * 1、安装长连接框架：composer require workerman/gateway-worker

 * 2、配置基本参数
 *      配置为文件为 config/gateway_worker.php（必须使用对应命令才能启动）
 *          配置端口startPort，pingData，eventHandler，其它默认就好
 *      eventHandler配置为app\index\logic\events\Events.php类，用于处理监听后的业务逻辑
 * 3、启动服务
 *      启动命令为：php think worker:gateway
 * 4、   nginx服务配置以支持/wss方式访问
 *      参考配置：
 *      location /wss
        {
            proxy_pass http://127.0.0.1:2000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header X-Real-IP $remote_addr;
        }
 * 5、JavaScript客户端建立连接并访问
 *      ws = new WebSocket("wss://boomim.playone.cn/wss");//这种访问方式需要nginx配置
        ws.onopen = function() {
            alert("连接成功");
            ws.send('hello,thinkphp');
            alert("给服务端发送一个字符串：hello,thinkphp");
        };
 */
class Events extends \think\worker\Events
{

    /**
     * onWorkerStart 事件回调
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
     *
     * @access public
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStart(Worker $businessWorker)
    {
        $app = new Application;
        //config([
        //    'database' => [
        //        // 数据库类型
        //        'type'        => 'mysql',
        //        // 服务器地址
        //        'hostname'    => '127.0.0.1',//,
        //        // 数据库名
        //        'database'    => 'cup_defense',
        //        // 数据库用户名
        //        'username'    => 'cup_defense',
        //        // 数据库密码
        //        'password'    => 'z8PMXE3PGsy7WiFP',
        //        // 数据库连接端口
        //        'hostport'    => 3306,
        //        // 数据库编码默认采用utf8
        //        'charset'     => 'utf8',
        //        // 连接dsn
        //        'dsn'             => '',
        //        // 数据库连接参数
        //        'params'          => [],
        //        // 数据库表前缀
        //        'prefix'          => '',
        //    ],
        //]);

        $app->initialize();
        // 输出数据库配置
        //Tools::log_to_write_txt(['onWorkerStart_database'=>config('database.')]);
        //// 加载数据库配置
        // 输出数据库配置
        //Tools::log_to_write_txt(['onWorkerStart_database'=>config('database.')]);

        // 初始化数据库连接
        //Db::init();
        //Db::connect();
        // 在工作进程开始时，可以在这里执行一次数据库查询
        //Db::table('fa_users')->find();
    }

    /**
     * onConnect 事件回调
     * 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
     *
     * @access public
     * @param  int       $client_id
     * @return void
     */
    public static function onConnect($client_id)
    {
        //一个连接只触发一次
        Tools::log_to_write_txt(['客户端完成TCP握手：'=>"[{$client_id}]"]);

        $json = BaseWssApi::json_wss('onConnect','连接成功',['client_id'=>$client_id]);
        Gateway::sendToCurrentClient($json);
    }

    /**
     * onWebSocketConnect 事件回调
     * 当客户端连接上gateway完成websocket握手时触发
     *
     * @param  integer  $client_id 断开连接的客户端client_id
     * @param  mixed    $data {
    "get":[

    ],
    "server":{
    "REQUEST_METHOD":"GET",
    "REQUEST_URI":"/wss",
    "SERVER_PROTOCOL":"HTTP/1.1",
    "HTTP_UPGRADE":"websocket",
    "HTTP_CONNECTION":"Upgrade",
    "HTTP_X_REAL_IP":"183.227.89.107",
    "HTTP_HOST":"127.0.0.1:2000",
    "SERVER_NAME":"127.0.0.1",
    "SERVER_PORT":"2000",
    "HTTP_PRAGMA":"no-cache",
    "HTTP_CACHE_CONTROL":"no-cache",
    "HTTP_USER_AGENT":"wechatdevtools desktopapp appservice port/62717 token/589065e467011760c777411fca2cd0aa runtime/2 MicroMessenger",
    "HTTP_ORIGIN":"https://boomim.playone.cn",
    "HTTP_SEC_WEBSOCKET_VERSION":"13",
    "HTTP_ACCEPT_ENCODING":"gzip, deflate, br",
    "HTTP_ACCEPT_LANGUAGE":"zh-CN,zh;q=0.9",
    "HTTP_CONTENT_TYPE":"application/json",
    "HTTP_REFERER":"https://servicewechat.com/wx55e10fb2834803d5/devtools/page-frame.html",
    "HTTP_SEC_WEBSOCKET_KEY":"uWOWC1AZahJOpS18hN3ZHA==",
    "HTTP_SEC_WEBSOCKET_EXTENSIONS":"permessage-deflate; client_max_window_bits",
    "QUERY_STRING":""
    },
    "cookie":[

    ]
    }
     * @return void
     */
    public static function onWebSocketConnect($client_id, $data)
    {

//        var_export($data);
        //对应客户端打开连接, 一个连接只触发一次
        Tools::log_to_write_txt(['客户端打开了websocket连接',$client_id,$data]);
        //$res = Tools::set_ok('ok',['client_id'=>$client_id,'msg'=>'客户端打开连接时，发送到服务端的消息：','data'=>$data]);
        //
        //Gateway::sendToCurrentClient(json_encode($res,JSON_UNESCAPED_UNICODE));
        //$json = BaseWssApi::json_wss('openConnect','打开连接成功',['client_id'=>$client_id,'data'=>$data]);
        //Gateway::sendToCurrentClient($json);
    }

    /**
     * onMessage 事件回调
     * 当客户端发来数据(Gateway进程收到数据)后触发
     *
     * 解析消息,根据action处理业务逻辑
     *
     * @access public
     * @param  int       $client_id
     * @param  mixed     $data
     * @return void
     */
    public static function onMessage($client_id, $data)
    {
        Tools::log_to_write_txt(['客户端发来数据(Gateway进程收到数据).client_id:'.$client_id,$data]);
        //$res = Tools::set_ok('ok',['client_id'=>$client_id,'msg'=>'你发来的消息我接收到了：',$client_id=>$data]);
        //Gateway::sendToClient($client_id,json_encode($res,JSON_UNESCAPED_UNICODE));

        //解析消息

        //解析action

        //调用业务逻辑&响应处理结果
        (new WssMessageLogic())->domsg($client_id,$data);
    }

    /**
     * onClose 事件回调 当用户断开连接时触发的方法
     *
     * @param  integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
        //GateWay::sendToAll("client[$client_id] logout\n");
        Tools::log_to_write_txt(['断开连接.client_id:'.$client_id]);

        //$url = 'https://boomim.playone.cn/api/Partnermerchants/offline';
        //Curl::curl_post($url,['clientid'=>$client_id]);

        (new UserLogic())->offline($client_id);
    }

    /**
     * onWorkerStop 事件回调
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     *
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStop(Worker $businessWorker)
    {
        //echo "WorkerStop\n";
        Tools::log_to_write_txt(['businessWorker进程退出时触发。每个进程生命周期内都只会触发一次.',$businessWorker]);
        //所有人离线，不需要修改所有用户离线状态，
        //因为离线后再上线clint_id会重新生成
    }
}