您的当前位置:首页>全部文章>文章详情

【linux版】tp5中使用GatewayWorker和Workerman

发表于:2023-01-19 14:58:05浏览:219次TAG: #ThinkPHP #PHP #linux #Workerman

安装

1、安装WorkerMan

composer require workerman/workerman

2、安装GatewayWorker

composer require workerman/gateway-worker

3、安装GatewayClient(作用:主动推送消息给客户端)

composer require workerman/gatewayclient

服务端

  • start.php(目录:与application同级别,作用:启动服务)
<?php
/**
Linux 启动Workerman
启动
以debug(调试)方式启动

php start.php start

以daemon(守护进程)方式启动

php start.php start -d

停止
php start.php stop

重启
php start.php restart

平滑重启
php start.php reload

查看状态
php start.php status
 */
ini_set('display_errors', 'on');
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("start.php not support windows.\n");
}
//检查扩展
if(!extension_loaded('pcntl'))
{
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
if(!extension_loaded('posix'))
{
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','push/Gate');
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';
  • 控制器:app\push\controller\Gate.php
<?php 
namespace app\push\controller;
use think\Controller;
use Workerman\Worker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use GatewayWorker\BusinessWorker;
class Gate extends Controller
{
    /**
     * 构造函数
     * @access public
     */
    public function __construct(){
        //初始化各个GatewayWorker
        //初始化register register 服务必须是text协议
        $register = new Register('text://0.0.0.0:1236');
        //初始化 bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'ChatBusinessWorker';
        // bussinessWorker进程数量
        $worker->count = 4;
        // 服务注册地址
        $worker->registerAddress = '127.0.0.1:1236';
        //设置处理业务的类,此处制定Events的命名空间
        $worker->eventHandler = 'app\push\controller\Events';
        // gateway 进程
        $gateway = new Gateway("Websocket://0.0.0.0:7272");
        // 设置名称,方便status时查看
        $gateway->name = 'ChatGateway';
        // 设置进程数,gateway进程数建议与cpu核数相同
        $gateway->count = 4;
        // 分布式部署时请设置成内网ip(非127.0.0.1)
        $gateway->lanIp = '127.0.0.1';
        // 内部通讯起始端口。假如$gateway->count=4,起始端口为2300
        // 则一般会使用2300 2301 2302 2303 4个端口作为内部通讯端口 
        $gateway->startPort = 2300;
        // 心跳间隔
        $gateway->pingInterval = 30;
        $gateway->pingNotResponseLimit = 1;
        // 心跳数据
        $gateway->pingData = '';
        // 服务注册地址
        $gateway->registerAddress = '127.0.0.1:1236';
        //运行所有Worker;
        Worker::runAll();
    }
}
  • 控制器:app\push\controller\Events.php(作用:业务处理)
<?php
namespace app\push\controller;
use think\Controller;
use \GatewayWorker\Lib\Gateway;
class Events extends Controller
{
    /**
     * 有消息时
     * @param integer $client_id 连接的客户端
     * @param mixed $message
     * @return void
     */
    public static function onMessage($client_id, $message)
    {

        $message = json_decode($message,true);
        $action = $message['action'];
        $data = $message['data'];
        switch ($action) {
            case 'ping'://发:{"action":"ping","data":{"online":1}}
                return;
                break;
            case 'line'://发:{"action":"line","data":{"type":"1i"}}
                $json = json_encode([
                    'action'=>'line',
                    'data'=>[],
                ]);
                break;
            default:
                return;
                break;
        }
        Gateway::sendToClient($client_id, $json);
    }

    /**
     * 当用户连接时触发的方法
     * @param integer $client_id 连接的客户端
     * @return void
     */
    public static function onConnect($client_id)
    {
        $json = json_encode([
                'action'=>'ping',
                'data'=>[
                    'online'=>1
                ]
            ]);
        Gateway::sendToClient($client_id, $json);
    }

    /**
     * 当用户断开连接时触发的方法
     * @param integer $client_id 断开连接的客户端
     * @return void
     */
    public static function onClose($client_id)
    {

    }

    /**
     * 当进程启动时
     * @param integer $businessWorker 进程实例
     */
    public static function onWorkerStart($businessWorker)
    {

    }

    /**
     * 当进程关闭时
     * @param integer $businessWorker 进程实例
     */
    public static function onWorkerStop($businessWorker)
    {

    }
}
  • 控制器:app\push\controller\Client.php(作用:主动推送消息给客户端)
<?php
namespace app\push\controller;
use GatewayClient\Gateway;
class Client
{
    /**
     * === 指定registerAddress表明与哪个GatewayWorker(集群)通讯。===
     * GatewayWorker里用Register服务来区分集群,即一个GatewayWorker(集群)只有一个Register服务,
     * GatewayClient要与之通讯必须知道这个Register服务地址才能通讯,这个地址格式为 ip:端口 ,
     * 其中ip为Register服务运行的ip(如果GatewayWorker是单机部署则ip就是运行GatewayWorker的服务器ip),
     * 端口是对应ip的服务器上start_register.php文件中监听的端口,也就是GatewayWorker启动时看到的Register的端口。
     * GatewayClient要想推送数据给客户端,必须知道客户端位于哪个GatewayWorker(集群),
     * 然后去连这个GatewayWorker(集群)Register服务的 ip:端口,才能与对应GatewayWorker(集群)通讯。
     * 这个 ip:端口 在GatewayClient一侧使用 Gateway::$registerAddress 来指定。
     * 
     * === 如果GatewayClient和GatewayWorker不在同一台服务器需要以下步骤 ===
     * 1、需要设置start_gateway.php中的lanIp为实际的本机内网ip(如不在一个局域网也可以设置成外网ip),设置完后要重启GatewayWorker
     * 2、GatewayClient这里的Gateway::$registerAddress的ip填写填写上面步骤1lanIp所指定的ip,端口
     * 3、需要开启GatewayWorker所在服务器的防火墙,让以下端口可以被GatewayClient所在服务器访问,
     *    端口包括Rgister服务的端口以及start_gateway.php中lanIp与startPort指定的几个端口
     *
     * === 如果GatewayClient和GatewayWorker在同一台服务器 ===
     * GatewayClient和Register服务都在一台服务器上,ip填写127.0.0.1及即可,无需其它设置。
     **/
    public function __construct()
    {
        Gateway::$registerAddress = '127.0.0.1:1236';
    }
    // GatewayClient支持GatewayWorker中的所有接口(Gateway::closeCurrentClient Gateway::sendToCurrentClient除外)
    //Gateway::sendToAll($data);
    //Gateway::sendToClient($client_id, $data);
    //Gateway::closeClient($client_id);
    //Gateway::isOnline($client_id);
    //Gateway::bindUid($client_id, $uid);
    //Gateway::isUidOnline($uid);
    //Gateway::getClientIdByUid($client_id);
    //Gateway::unbindUid($client_id, $uid);
    //Gateway::sendToUid($uid, $dat);
    //Gateway::joinGroup($client_id, $group);
    //Gateway::sendToGroup($group, $data);
    //Gateway::leaveGroup($client_id, $group);
    //Gateway::getClientCountByGroup($group);
    //Gateway::getClientSessionsByGroup($group);
    //Gateway::getAllClientCount();
    //Gateway::getAllClientSessions();
    //Gateway::setSession($client_id, $session);
    //Gateway::updateSession($client_id, $session);
    //Gateway::getSession($client_id);
    //////////////////// 业务 //////////////////////
}