Easyswoole 自定义命令行、自定义进程 和 Bridge的进程交互 拿取主服务内部的数据

需求背景

我需要在命令行中能比较简单的调取当前Websocket的在线数量
我这边在每个Websocket onOpen的时候使用swoole的table 做了一个fd的存储

碰到的问题和思路 Bridge的交互

在easyswoole的普通命令行中,是独立的临时进程,故拿不到主服务的内部数据
好在easyswoole有Bridge的桥接进程,提供给外部进程进行交互获取 主服务内部的数据

注册Bridge的Command

public static function mainServerCreate(EventRegister $register)
{
  \EasySwoole\EasySwoole\Bridge\Bridge::getInstance()->getCommandContainer()->set(new BridgeWsCommand());
}



BridgeWsCommand.php

位于:App/Command/BridgeWsCommand.php  (可根据自己项目调整)

<?php

namespace App\Command;

use App\Table\Fdtable;
use App\Table\UseridTable;
use EasySwoole\Bridge\Package;
use EasySwoole\EasySwoole\Bridge\AbstractCommand;

class BridgeWsCommand extends AbstractCommand
{
    public function commandName(): string
    {
        return "websocket";
    }

    protected function count(Package $package, Package $response)
    {
        // 自己的业务逻辑
        $data = Fdtable::getInstance()->getCount();
        $response->setArgs($data);
    }
}

自定义的Command

位于:App/Command/WebsocketCommand.php 

<?php

namespace App\Command;

use App\Table\Fdtable;
use App\Table\UseridTable;
use EasySwoole\Bridge\Package;
use EasySwoole\Command\AbstractInterface\CommandHelpInterface;
use EasySwoole\Command\AbstractInterface\CommandInterface;
use EasySwoole\Command\CommandManager;
use EasySwoole\EasySwoole\Bridge\Bridge;
use EasySwoole\EasySwoole\Command\Utility;
use Swoole\Coroutine\Scheduler;

class WebsocketCommand implements CommandInterface
{

    public function commandName(): string
    {
        // TODO: Implement commandName() method.
        return "websocket";
    }

    public function exec(): ?string
    {
        // TODO: Implement exec() method.
        $argv = CommandManager::getInstance()->getOriginArgv();

        if (count($argv) < 3) {
            echo "please input the action param!" . PHP_EOL;
            return null;
        }

        // remove test
        array_shift($argv);

        // 获取 action 参数
        $action = $argv[1];

        // 下面就是对 自定义命令 的一些处理逻辑
        if (!$action) {
            echo "please input the action param!" . PHP_EOL;
            return null;
        }

        // 获取 option 参数
        $optionArr = $argv[2] ?? [];

        switch ($action) {
            case "count":
                $run = new Scheduler();
                $run->add(function () use (&$result) {
                    $result = Utility::bridgeCall($this->commandName(), function (Package $package) {
                        $data = $package->getArgs();
                        return $data;
                    }, 'count');
                });
                $run->start();
                echo sprintf("当前websocket在线总数:%s" . PHP_EOL, $result);
                break;
            default:
                echo "the action {$action} is not existed!" . PHP_EOL;
        }
        return null;
    }

    public function help(CommandHelpInterface $commandHelp): CommandHelpInterface
    {
        $commandHelp->addAction('count', '输出websocket的在线数量');
        return $commandHelp;
    }

    public function desc(): string
    {
        return " 在线维护 websocket";
    }
}

注册Command

修改Easyswoole 根目录下的bootstarp.php

<?php
//全局bootstrap事件
date_default_timezone_set('Asia/Shanghai');
EasySwoole\EasySwoole\Core::getInstance()->initialize();
\EasySwoole\Command\CommandManager::getInstance()->addCommand(new \App\Command\WebsocketCommand());

ps

目前我使用的easyswoole版本 3.4.4 当在bootstarp.php 中
EasySwoole\EasySwoole\Core::getInstance()->initialize(); 
注册了初始化 在使用默认的命令行 如 task、server、process 会出现初始化两次的情况,已反馈给官方人员
临时的处理方式:
/vendor/easyswoole/easyswoole/src/Command/DefaultCommand/*.php
下都有一个exec函数 函数内部有
Core::getInstance()->initialize();
将这个注释掉
(可做可不做,如没性能瓶颈的话无所谓,执行整个流程1s不到)

总结

如果需要在自定义命令行内获取主服务内部的数据,则需要和Bridge进程进行交互
Easyswoole底层已经帮我们写好了socket的交互,所以我们需要注册两个Command

1. Bridge的Command 获取内部数据的业务逻辑

2. 注册Easyswoole 命令行的Command 做与Bridge的数据交互获取,和控制台的窗口数据展示

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值