TP6+gatewayWorker

在这里插入图片描述

安装
composer require topthink/think-worker

修改配置
config/gateway_worker.php

~~~
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:gateway 指令有效
// +----------------------------------------------------------------------
return [
    // 扩展自身需要的配置
    'protocol'              => 'websocket', // 协议 支持 tcp udp unix http websocket text
    'host'                  => '0.0.0.0', // 监听地址
    'port'                  => 9501, // 监听端口 #修改
    'socket'                => '', // 完整监听地址
    'ssl'                   => true,//#修改
    'transport'             => 'ssl',//#修改
    'context'               => [
        "ssl" => [
            'local_cert'  => '/www/server/panel/vhost/cert/www.baidu.com.cn/fullchain.pem',//#修改
            'local_pk'    => '/www/server/panel/vhost/cert/www.baidu.com.cn/privkey.pem',//#修改
            'verify_peer' => false,//#修改
        ],
    ], // socket 上下文选项
    'register_deploy'       => true, // 是否需要部署register
    'businessWorker_deploy' => true, // 是否需要部署businessWorker
    'gateway_deploy'        => true, // 是否需要部署gateway

    // Register配置
    'registerAddress'       => '127.0.0.1:1237',//#修改

    // Gateway配置
    'name'                  => 'thinkphp',
    'count'                 => 1,
    'lanIp'                 => '127.0.0.1',
    'startPort'             => 2000,
    'daemonize'             => false,
    'pingInterval'          => 30,
    'pingNotResponseLimit'  => 0,
    'pingData'              => '{"type":"ping"}',

    // BusinsessWorker配置
    'businessWorker'        => [
        'name'         => 'BusinessWorker',
        'count'        => 1,
        'eventHandler' => 'app\webscoket\Events',//#修改
    ],

];

~~~

新建事件处理逻辑类

app/webscoket/Events.php

<?php
/**
 * Created by PhpStorm.
 * User: Pasa吴
 * Date: 2023/2/20
 * Time: 14:21
 */

namespace app\webscoket;


use app\service\SearchUserService;
use app\service\UserService;
use GatewayWorker\Lib\Gateway;
use Workerman\Worker;
use think\worker\Application;


class Events
{
    /**
     * onWorkerStart 事件回调
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
     * @access public
     * @param \Workerman\Worker $businessWorker
     * @return void
     */
    public static function onWorkerStart(Worker $businessWorker)
    {
        $app = new Application;
        $app->initialize();
    }

    /**
     * onConnect 事件回调
     * 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
     * @access public
     * @param int $client_id
     * @return void
     */
    public static function onConnect($client_id)
    {
        xdebug(compact('client_id'), 'onConnect', 'workerman');
        Gateway::sendToCurrentClient(json_encode(['type' => 'notice', 'mes' => $client_id . ':连接成功'], JSON_UNESCAPED_UNICODE));
    }

    /**
     * onWebSocketConnect 事件回调
     * 当客户端连接上gateway完成websocket握手时触发
     * @param integer $client_id 断开连接的客户端client_id
     * @param mixed $data
     * @return void
     */
    public static function onWebSocketConnect($client_id, $data)
    {
    }

    /**
     * onMessage 事件回调
     * 当客户端发来数据(Gateway进程收到数据)后触发
     * @access public
     * @param int $client_id
     * @param mixed $data
     * @return void
     */
    public static function onMessage($client_id, $data)
    {
        xdebug(compact('client_id', 'data'), 'onMessage', 'workerman');
        $param = json_decode($data);

        if (isset($param->type) && $param->type) {
            switch ($param->type) {
                //登录
                case 'login':
                    if (isset($param->token) && $param->token) {
                        //解析token
                        /* @var UserService $UserService */
                        $UserService = app(UserService::class);
                        $uid         = $UserService->parseToken($param->token);
                        if ($uid) {
                            //绑定UID
                            Gateway::bindUid($client_id, $uid);
                            Gateway::sendToUid($uid, json_encode(['type' => 'notice', 'mes' => '登录成功UID:' . $uid], JSON_UNESCAPED_UNICODE));
                            return;
                        }
                        Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:token无效'], JSON_UNESCAPED_UNICODE));
                    }
                    break;
                //加入房间
                case 'join':
                    if (isset($param->room) && $param->room) {
                        //加入房间
                        Gateway::joinGroup($client_id, $param->room);
                        //获取UID
                        $uid = Gateway::getUidByClientId($client_id);
                        //向房间所有人发消息
                        Gateway::sendToGroup($param->room, json_encode(['type' => 'notice', 'mes' => "加入{$param->room}房间UID:" . $uid], JSON_UNESCAPED_UNICODE));
                        return;
                    }
                    Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:加入房间失败'], JSON_UNESCAPED_UNICODE));
                    break;
                //离开房间
                case 'leave':
                    if (isset($param->room) && $param->room) {
                        //将 client_id 离开组
                        Gateway::leaveGroup($client_id, $param->room);
                        //获取UID
                        $uid = Gateway::getUidByClientId($client_id);
                        //向房间所有人发消息
                        Gateway::sendToGroup($param->room, json_encode(['type' => 'notice', 'mes' => "离开{$param->room}房间UID:" . $uid], JSON_UNESCAPED_UNICODE));
                        return;
                    }
                    Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:离开房间失败'], JSON_UNESCAPED_UNICODE));
                    break;
                //正在输入
                case 'entering':
                    if (isset($param->room) && $param->room) {
                        //获取UID
                        $uid  = Gateway::getUidByClientId($client_id);
                        $list = Gateway::getUidListByGroup($param->room);
                        foreach ($list as $key => $value) {
                            if ($value == $uid) {
                                continue;
                            }
                            //除了本人往房间所有发送消息
                            Gateway::sendToUid($value, json_encode(['type' => 'entering', 'mes' => '正在输入UID:' . $uid], JSON_UNESCAPED_UNICODE));
                        }
                        return;
                    }
                    Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:正在输入失败'], JSON_UNESCAPED_UNICODE));
                    break;
                //输入结束
                case 'enter':
                    if (isset($param->room) && $param->room) {
                        //获取UID
                        $uid  = Gateway::getUidByClientId($client_id);
                        $list = Gateway::getUidListByGroup($param->room);
                        foreach ($list as $key => $value) {
                            if ($value == $uid) {
                                continue;
                            }
                            //除了本人往房间所有发送消息
                            Gateway::sendToUid($value, json_encode(['type' => 'enter', 'mes' => '输入结束UID:' . $uid], JSON_UNESCAPED_UNICODE));
                        }
                        return;
                    }
                    Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:停止输入失败'], JSON_UNESCAPED_UNICODE));
                    break;
                //消息
                case 'mes':
                    if (isset($param->room) && $param->room) {
                        //获取UID
                        $uid  = Gateway::getUidByClientId($client_id);
                        Gateway::sendToGroup($param->room, json_encode(['type' => 'mes', 'mes' => '发送消息UID:' . $uid], JSON_UNESCAPED_UNICODE));
                        Gateway::sendToGroup($param->room, json_encode(['type' => 'mes', 'mes' => $param->message], JSON_UNESCAPED_UNICODE));
                        return;
                    }
                    Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:发送消息失败'], JSON_UNESCAPED_UNICODE));
                    break;
            }
        }
    }

    /**
     * onClose 事件回调 当用户断开连接时触发的方法
     * @param integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
        xdebug(compact('client_id'), 'onClose', 'workerman');
        GateWay::sendToAll(json_encode(['type' => 'close']));
    }

    /**
     * onWorkerStop 事件回调
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     * @param \Workerman\Worker $businessWorker
     * @return void
     */
    public static function onWorkerStop(Worker $businessWorker)
    {
        echo "WorkerStop\n";
    }
}

前端代码

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<button onclick="login()">登录</button>
<button onclick="join()">加入房间</button>
<button onclick="leave()">离开房间</button>
<button onclick="entering()">正在输入</button>
<button onclick="enter()">停止输入</button>
<input type="text" id="message">
<button onclick="send()">发送</button>

<div id="notice">通知<div>

    <script>
        var ws = new WebSocket("wss://www.baidu.cn:9501");
        ws.onopen = function(){
            console.log('连接成功');
        }

        //登录
        function login(){
            var token = prompt('请输入token');
            var param = {type:'login', token:token}

            ws.send(JSON.stringify(param));
        }

        //加入房间
        function join()
        {
            var room = prompt('请输入房间号');
            var param = {type:'join', room:room}
            ws.send(JSON.stringify(param));
        }

        //离开房间
        function leave()
        {
            var room = prompt('请输入房间号');
            var param = {type:'leave', room:room}
            ws.send(JSON.stringify(param));
        }

        //正在输入
        function entering()
        {
            var room = prompt('请输入房间号');
            var param = {type:'entering', room:room}
            ws.send(JSON.stringify(param));
        }

        //输入结束
        function enter()
        {
            var room = prompt('请输入房间号');
            var param = {type:'enter', room:room}
            ws.send(JSON.stringify(param));
        }

        //发送消息
        function send()
        {
            var message = document.getElementById('message').value;
            var room = prompt('请输入接收消息的房间号')
            var param = {type:'mes', room:room, message:message}
            ws.send(JSON.stringify(param));
        }

        //接受服务端消息
        ws.onmessage = function(data){
            data = data.data;
            console.log(data,'onmessage');
            data = JSON.parse(data);

            switch (data.type){
                //调试用的,不需要理会
                case 'notice':
                    console.log(data.mes,'notice');
                    document.getElementById('notice').innerHTML+='<br>';
                    document.getElementById('notice').innerHTML+=data.mes;
                    break;
                //正在输入,显示正在输入
                case 'entering':
                    console.log(data.mes,'entering');
                    document.getElementById('notice').innerHTML+='<br>';
                    document.getElementById('notice').innerHTML+=data.mes;
                    break;
                //输入结束,显示老师名称
                case 'enter':
                    console.log(data.mes,'enter');
                    document.getElementById('notice').innerHTML+='<br>';
                    document.getElementById('notice').innerHTML+=data.mes;
                    break;
                //websocket错误,弹出内容提示
                case 'error':
                    console.log(data.mes,'enter');
                    document.getElementById('notice').innerHTML+='<br>';
                    document.getElementById('notice').innerHTML+=data.mes;
                    break;
                //发送消息,调用聊天内容列表接口
                case 'mes':
                    console.log(data.mes,'enter');
                    document.getElementById('notice').innerHTML+='<br>';
                    document.getElementById('notice').innerHTML+=data.mes;
                    break;
                default:
            }
            console.log(data.type,'onmessage2');
        }

        ws.onclose = function(){
            console.log('连接断开');
        }


    </script>
</body>
</html>

在服务器根目录下启动命令

php think worker:gateway
php think worker:gateway status
php think worker:gateway start
php think worker:gateway -d
php think worker:gateway stop
php think worker:gateway reload
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值