<?php

namespace app\shared\controller;
 
use swoole\Server as swoole_server;
 
class Server extends swoole_server{
    // 监听所有地址
    protected $host = '0.0.0.0';
    //监听 9501 端口
    protected $port = 9501;
    //指定运行模式为多进程
    protected $mode = SWOOLE_PROCESS;
    protected $serverType = 'socket';
    // 指定 socket 的类型为 ipv4 的 tcp socket
    protected $sockType = SWOOLE_SOCK_TCP;
    //配置项
    protected $option = [
        /**
         *  设置启动的worker进程数
         *  业务代码是全异步非阻塞的，这里设置为CPU的1-4倍最合理
         *  业务代码为同步阻塞，需要根据请求响应时间和系统负载来调整
         */
        'worker_num' => 4,
        // 守护进程化
        'daemonize'  => false,
        // 监听队列的长度
        'backlog'    => 128
    ];
 
    public function __construct(){
        parent::__construct();swoole_set_process_name("swoole_websocket");//设置进程名称，方便重启服务
    }
 
    /**
     * 握手连接
     * @param $server
     * @param $request
     */
    public function onOpen($server, $request){
        echo "server: handshake success with fd{$request->fd}\n";
        //创建新在线fd
        $redis = new \app\common\controller\RedisBase();
        $redis->setFD($request->fd);
 
        $result = $this->getOrder();
        if($result > 0) {
            foreach ($server->connections as $fd) {
                $server->push($fd, json_encode(['data' => ['count' => $result], 'code' => 200, 'message' => 'getOrder']));
            }
        }
    }
 
    /**
     * 定时执行广播推送
     * @param $server
     * @param $workerId
     */
    public function onWorkerStart($server, $workerId){
        if ($workerId == 0) {
            # 定时推送数据
            $server->tick(5000, function() use ($server) {
                $result = $this->getOrder();
                if($result > 0) {
                    foreach ($server->connections as $fd) {
                        $server->push($fd, json_encode(['data' => ['count' => $result], 'code' => 200, 'message' => 'getOrder']));
                    }
                }
            });
        }
    }
 
    /**
     * 发送消息（客户端触发）
     * @param $server
     * @param $frame
     */
    public function onMessage($server, $frame){
        $result = $this->getOrder();
        if($result > 0) {
            foreach ($server->connections as $fd) {
                $server->push($fd, json_encode(['data' => ['count' => $result], 'code' => 200, 'message' => 'getOrder']));
            }
        }
    }
 
    /**
     * 发送消息（链接触发）
     * @param $server
     * @param $frame
     */
    public function onRequest($server, $frame){
 
        $result = $this->getOrder();
        if($result > 0) {
            $redis = new \app\common\controller\RedisBase();
            $fds = $redis->getFD();
            if($fds) {
                //存在在线用户才进行推送
                foreach ($fds as $fd) {
                     //校验fd是否存在
                    $res_fd = $this->swoole->exist($fd);
                    if($res_fd) {
                        $this->swoole->push($fd, json_encode(['data' => ['count' => $result], 'code' => 200, 'message' => 'getOrder']));
                    }else{
                        $redis = new \app\common\controller\RedisBase();
                        $redis->delFD($fd);
                    }
                }
            }
        }
    }
 
    /**
     * 退出
     * @param $server
     * @param $fd
     */
    public function onClone($server, $fd){
        echo "client {$fd} closed\n";
        //删除在线fd
        $redis = new \app\common\controller\RedisBase();
        $redis->delFD($fd);
    }
 
}
