<?php

// +----------------------------------------------------------------------
// | framework
// +----------------------------------------------------------------------
// | 版权所有 2014~2018 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
// +----------------------------------------------------------------------
// | 官方网站: http://framework.thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | github开源项目:https://github.com/zoujingli/framework
// +----------------------------------------------------------------------

namespace app\act\socket;

use think\worker\Server;

class Worker extends Server
{

    protected $clients = array();  //保存客户端信息
    protected $socket = 'websocket://0.0.0.0:2346';

    /**
     * 收到信息 客户端必须传形如 我自己的uid加密串signature=xxx&to=xxx对方的非加密uid&msg=你好,之后再进行非对称加密
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        # 解密data 后续开发

        # 解析data
        parse_str($data, $data);

        # 验证有效性
        if (!isset($data['signature']) && !isset($data['to']) && !isset($data['msg'])) {
            # 通知客户端有问题
            $connection->send('status=2&msg=error');
        } else {
            $data['user'] = $this->load('api/lib/user')->decode($data['signature']);
            if (!$data['user']) {
                $connection->send('status=2&msg=error');
            }

            if (isset($data['user']['uid']) && $data['user']['uid'] > 0 && $data['user']['uid'] != $data['to']) {
                # 连接成功

                # 检查当前客户端里有没有,没有则保存
                if (!isset($this->clients[$data['user']['uid']])) {
                    # 双方用户信息都由客户端获取
                    $ip = $connection->getRemoteIp();
                    $port = $connection->getRemotePort();

                    $this->clients[$data['user']['uid']]] = array
                    (
                        'ip' => $ip,
                        'port' => $port,
                        'connection' => $connection
                    );
                }

                # 写入数据库,状态为未读

                # 检查要发送的信息,有没有在客户端列表里
                if (isset($this->clients[$data['to']])) {
                    # 在线,把消息发过去,客户端看过之后再设置为已读
                    $this->clients[$data['to']]['connection']->send($data['msg']);
                } else {
                    # 不在线,等该用户上线再读取就行了。不用这里做什么了。
                }

            } else {
                $connection->send('status=2&msg=error');
            }
        }
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        unset($this->clients[$connection->getRemoteIp()]);
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {

    }
}