swoole+redis制作简单的聊天工具,适配tp5.1

先上链接;http://chenshuixing.com:8812/chat/chat.html

功能比较简单,可以一对一聊天,也可以群聊。下面是服务器代码,加载了tp5.1框架

<?php
/**
 * ws 优化 基础类库
 * User: singwa
 * Date: 18/3/2
 * Time: 上午12:34
 */

class Ws {
    CONST HOST        = "0.0.0.0";      // 0.0.0.0表示监听所有地址
    CONST PORT        = 8812;           // 监听端口 8811作为HTTP服务端口

    public $ws = null;
    public function __construct() {
        $this->ws = new swoole_websocket_server(self::HOST, self::PORT);

        // 同时保留http服务的配置
        $this->ws->set(
            [
                'worker_num' => 5,
                'task_worker_num' => 1,
                'enable_static_handler' => true,
                'document_root' => '/usr/local/nginx/html/zhibo/public/static', //静态资源目录
            ]
        );
        $this->ws->on("start", [$this, 'onStart']);
        $this->ws->on("open", [$this, 'onOpen']);
        $this->ws->on("message", [$this, 'onMessage']);
        $this->ws->on('WorkerStart',[$this,"onWorkerStart"]);
        $this->ws->on("request",[$this,'onRequest']);
        
        $this->ws->on("task", [$this, 'onTask']);
        $this->ws->on("finish", [$this, 'onFinish']);
        $this->ws->on("close", [$this, 'onClose']);

        $this->ws->start();
    }

    public function onStart($server)
    {
        // onStart调用时修改主进程名称,方便重启脚本能够找到对应的pid
    }

    /**
     * 监听websocket连接事件
     * @param $ws
     * @param $request  
     */
    public function onOpen($ws, $request) {

       $client_list = \app\common\lib\Predis::getInstance()->sMembers(config('live.client_ids_key'));
       \app\common\lib\Predis::getInstance()->sAdd(config('live.client_ids_key'), $request->fd);
       \app\common\lib\Predis::getInstance()->set(config('live.client_ids_key').$request->fd, $request->get['name']);

       $list = [];
       if (!empty($client_list)) {
            foreach ($client_list as $value) {
                $row = [];
                $row['id'] = $value;
                $row['name'] = \app\common\lib\Predis::getInstance()->get(config('live.client_ids_key').$value);
                $list[] = $row;
            }
       }
       // 给当前链接的客户播报现在所有的在线客户
       $ws->push($request->fd,json_encode(['action'=>'online_list','data'=>$list]));
       // 给所有在线客户播报当前新连接的客户
       if (!empty($client_list)) {
            foreach ($client_list as $value) {
                if ($request->fd != $value) {
                    $ws->push($value,json_encode(['action'=>'online_list','data'=>[['id'=>$request->fd,'name'=>$request->get['name']]]]));
                }
            }
        }
    }

    /**
     * 此事件在Worker进程/Task进程启动时发生
     * @param  [type] $serv      [description]
     * @param  [type] $worker_id [description]
     * @return [type]            [description]
     */
    public function onWorkerStart($serv, $worker_id)
    {
        // 加载php的核心文件进来
        define('APP_PATH', __DIR__ . '/../../application/');
        require __DIR__ . '/../../thinkphp/base.php';

        think\Container::get('app', [APP_PATH]) ->run()->send();
       
    }


    /**
     * 监听ws消息事件
     * @param $ws
     * @param $frame 包含客户端fd,data
     */
    public function onMessage($ws, $frame) {
        $rec_msg = json_decode($frame->data);
        var_dump($rec_msg);
        $send_info = ['action'=>'say','data'=>['name'=>$rec_msg->name,'content'=>$rec_msg->content,'time'=>$rec_msg->time] ];
        if ($rec_msg->to_client) {
            // 发送给对象和自己
            $this->ws->push($rec_msg->to_client, json_encode($send_info));
            $this->ws->push($frame->fd, json_encode($send_info));
        } else {
            // 广播给所有人
            $client_list = \app\common\lib\Predis::getInstance()->sMembers(config('live.client_ids_key'));
            foreach ($client_list as $value) {
                $this->ws->push($value, json_encode($send_info));
            }
        }
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $workerId
     * @param $data
     */
    public function onTask($serv, $taskId, $workerId, $data) {
        print_r($data);
        // 耗时场景 10s
        sleep(10);
        return "on task finish"; // 告诉worker
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $data
     */
    public function onFinish($serv, $taskId, $data) {
        echo "taskId:{$taskId}\n";
        echo "finish-data-sucess:{$data}\n";
    }

    /**
     * ws断开
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd) {
        \app\common\lib\Predis::getInstance()->sRem(config('live.client_ids_key'), $fd);
        \app\common\lib\Predis::getInstance()->del(config('live.client_ids_key').$fd);

        $client_list = \app\common\lib\Predis::getInstance()->sMembers(config('live.client_ids_key'));
        // 为线上客户播报该客户下线
        if(!empty($client_list)) {
            $data = ['action'=>'offline', 'data'=>['id'=>$fd]];
            foreach ($client_list as $key => $value) {
               $ws->push($value,json_encode($data));
            }
        }
    }

    /**
     * http请求
     * @param  [type] $request  [description]
     * @param  [type] $response [description]
     * @return [type]           [description]
     */
    public function onRequest($request,$response)
    {
        $_GET = array();
        if (!empty($request->get)) {
            foreach ($request->get as $key => $value) {
                $_GET[$key] = $value;
            }
        }
        $_POST = array();
        if (!empty($request->post)) {
            foreach ($request->post as $key => $value) {
                $_POST[$key] = $value;
            }
        }
        // 每次post接口的时候,加入对象
        $_POST['http_server'] = $this->ws;

        $_FILES = array();
        if (!empty($request->files)) {
            foreach ($request->files as $key => $value) {
                $_FILES[strtoupper($key)] = $value;
            }
        }
        $_SERVER = array();
        if (!empty($request->server)) {
            foreach ($request->server as $key => $value) {
                $_SERVER[strtoupper($key)] = $value;
            }
        }
        if (!empty($request->header)) {
            foreach ($request->header as $key => $value) {
                $_SERVER[strtoupper($key)] = $value;
            }
        }
        
         // 2. thinkphp执行应用
        ob_start();
        try{
            think\Container::get('app', [APP_PATH])
                ->run()
                ->send();
        }catch(\Exception $e){
            echo 'Caught exception: ',  $e->getMessage(), "\n";
        }

        $res = ob_get_contents();
        ob_end_clean();
        $response->end($res);
      
    }

}

$obj = new Ws();

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

runtoweb3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值