前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >社区分享〡Workerman中利用popen实现多进程Web SSH

社区分享〡Workerman中利用popen实现多进程Web SSH

作者头像
Tinywan
发布于 2025-01-23 11:47:45
发布于 2025-01-23 11:47:45
9600
代码可运行
举报
文章被收录于专栏:开源技术小栈开源技术小栈
运行总次数:0
代码可运行

起源

来源于群里兔子大佬 @chaz6chez 的分享,自己整理测试了下。

群友询问如何进程异步执行命令行任务,且有通知机制,想用来做web ssh,兔子大佬指导可以通过popen来实现:

群友讨论

实践

测试使用的是 workerman5.0 版本,基于兔佬提供是伪代码进行调整,使用websocket交互

在项目根目录新建start.php文件,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php

require_once __DIR__ . '/vendor/autoload.php';

date_default_timezone_set('Asia/Shanghai');

//进程池类
class ProcessPool
{
    private array $processes = [];
    public int $maxProcesses;

    public function __construct($maxProcesses = 5)
    {
        $this->maxProcesses = $maxProcesses;
    }

    //添加进程 popen打开的进程执行完会退出,不做复用
    public function add(string $command)
    {
        $process           = popen($command, 'r');
        $this->processes[] = $process;
        return $process;
    }

    // 释放进程
    public function releaseProcess($process): void
    {
        $key = array_search($process, $this->processes);
        if ($key !== false) {
            unset($this->processes[$key]); // 从活动进程池移除
        }
    }

    // 获取池中的所有进程数量
    public function processCount(): int
    {
        return count($this->processes);
    }
}

// 创建一个websocket Worker
$task = new \Workerman\Worker("websocket://0.0.0.0:3232");

// 初始化进程池
$processPool = new ProcessPool(5);

// 添加定时器,每秒打印进程数
$task->onWorkerStart = function (\Workerman\Worker $worker) use ($processPool) {
    \Workerman\Timer::add(1, function () use ($processPool) {
        var_dump('[' . date('H:i:s') . '] 活动进程数:' . $processPool->processCount());
    });
};

$task->onMessage = function (Workerman\Connection\TcpConnection $connection, $str) use ($processPool) {
    $data = json_decode($str, JSON_OBJECT_AS_ARRAY);
    $command = $data['command'] ?? '';
    if (empty($command)) {
        return $connection->send('无效命令');
    }

    //超过最大进程数时阻塞等待退出
    if ($processPool->processCount() >= $processPool->maxProcesses) {
        return $connection->send('使用进程数已达最大数,等待中...');
    }

    // 获取一个进程资源
    $process = $processPool->add($command);
    if (is_resource($process)) {

        // 创建读事件
        \Workerman\Worker::$globalEvent->onReadable($process, function ($pipe) use ($connection, $process, $processPool) {
            // 读取进程输出
            $output = fread($pipe, 8192);
            if ($output === false || feof($pipe)) {
                // 进程结束,释放资源
                fclose($pipe);
                $processPool->releaseProcess($pipe);
                $connection->send("进程结束.");
                \Workerman\Worker::$globalEvent->offReadable($process);
            } else {
                // 将输出发送给客户端
                $connection->send($output);
            }
        });

        return true;

    } else {
        return $connection->send("服务繁忙,请稍后重试.");
    }
};

\Workerman\Worker::runAll();

测试

项目根目录新建一个command.php文件,用于测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?php

for ($i = 0; $i < 5; $i++) {
    sleep(1);
    echo '测试' . $i . PHP_EOL;
}

php start.php start启动项目,前端使用 【WebSocket 测试工具】进行连接,发送消息执行命令:/usr/bin/php8.2 command.php

websocket 调试工具

执行pstree -ap | grep -C 20 /usr/bin/php8.2,可以看到有 5 个进程在跑,popen 打开的command.php进程执行完成后,就会自动退出。

进程查看

总结

通过 workerman 和 popen 可以异步进程执行命令,前端再搭配xterm.js就可以做 web ssh了;当然还可以有很多适用的场景,比如用 workerman 拉起think-queue进程等等,自行拓展...

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PHP实现Workerman实例 高性能PHP Socket即时通讯框架
如果需要自定义参数,可以在config/worker_server.php中进行配置,包括:
OwenZhang
2021/12/08
1.1K1
这次让我们真的读一下Workerman源码(六)
在经过了一个如沐春风、令人神清气爽而又愉悦的工作周后(具体发生了什么你们心里应该有数),总算可以回到以往周六日的节奏了。实际上对于我来说,没有严格意义上的周六日,一直在做事情,只不过所做事情的贡献对象不同而已。WM我已经叨叨了五个章节了,今天我想聊聊关于Workerman进程管理部分的相关源码,如果前五个章节你们都已经仔细研究过了,那么现在阅读Workerman进程管理部分的源码应该会是易如反掌了。
老李秀
2019/12/26
1.7K0
windows下WorkerMan实现简单的多人在线聊天
Workerman是一款纯PHP开发的开源高性能的PHP socket 服务框架。
一个淡定的打工菜鸟
2018/09/06
3.1K0
windows下WorkerMan实现简单的多人在线聊天
【黄啊码】thinkphp6结合workerman、websocket案例
安装workerman教程看这里——》https://markwcm.blog.csdn.net/article/details/119084920
黄啊码
2021/09/26
9970
开源高性能PHP应用容器workerman一对一聊天多人聊天
Workerman 是一款纯 PHP 开发的开源高性能 PHP 应用容器,它突破了传统 PHP 应用的限制,能够开发高性能的实时网络应用。它不是传统的 MVC 框架,而是一个底层通用的服务框架,支持 TCP、UDP、HTTP、WebSocket 等多种协议,适用于开发即时通讯、物联网、游戏服务器、高性能 HTTP 服务等多种应用。
Tinywan
2025/02/27
1571
开源高性能PHP应用容器workerman一对一聊天多人聊天
Yii2结合Workerman的websocket示例详解
本文主要给大家介绍了关于Yii2结合Workerman的websocket的相关内容,两者都是好东西,我就想着能不能结合起来,这样Yii2出现瓶颈的时候有些业务就可以平滑地迁移到Workerman中。下面话不多说了,来随着小编来一起看看详细的介绍吧
子润先生
2021/07/13
1K0
workerman5.0篇〡异步非阻塞协程HTTP客户端
workerman/http-client 是一个异步http客户端组件。所有请求响应异步非阻塞,内置连接池,消息请求和响应符合PSR7规范。
Tinywan
2025/01/10
1270
workerman5.0篇〡异步非阻塞协程HTTP客户端
workerman5.0篇〡Fiber、Swoole、Swow三协程并行运行
Fiber协程,在webman框架安装后,直接启动webman,事件驱动默认会切换到revolt/event-loop事件驱动。
Tinywan
2025/01/07
3030
workerman5.0篇〡Fiber、Swoole、Swow三协程并行运行
unity3d 对接 workerman 实现联机游戏功能案例分享
客户端是 C#,就简单先以和服务器端连接,发送,接收做例子,进一步就是方块移动,坐标传递。
用户7718188
2022/11/06
4390
workerman如何通过reusePort解决Linux内核进程惊群问题?
workerman使用pcntl_fork()来实现master/worker的多进程模型,每个worker进程通过使用stream_socket_server()函数来创建socket,由于fork创建的worker进程具备亲缘关系,所以不同的worker进程可以对相同的端口监听;不同worker进程监听相同的socket,在该socket存在事件时,所有监听该socket的worker进程会被唤醒,所有worker进程对socket资源进行抢占式处理,但最终只有一个worker进程可以对socket进行accept;在这个过程中就存在n-1个worker进程是无效调度的,仅仅只是被唤起了然后抢占失败并再次入眠。
Tinywan
2024/01/29
3270
workerman如何通过reusePort解决Linux内核进程惊群问题?
workerman的websocket的wss实例
Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。
OwenZhang
2022/05/30
3.8K7
workerman的websocket的wss实例
[源码解析] 并行分布式任务队列 Celery 之 多进程架构和模型
Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度。因为 Celery 通过多进程来提高执行效率,所以本文将带领大家初步了解 Celery 之 多进程架构和模型。
罗西的思考
2021/04/16
1.4K0
[源码解析] 并行分布式任务队列 Celery 之 多进程架构和模型
兔佬 l webman/workerman的协程基建套件及分享
这段时间本身比较忙,也很少在关注技术相关的点,上个月空了刚好有时间看看群里,结果发现大家在讨论协程以及webman/workerman的劣势-阻塞退化问题,本来说是稍稍提两下实现方向,结果一来二去直接弄了一个插件出来,经过反反复复修改,最后发布了webman-coroutine插件
Tinywan
2024/10/10
2090
兔佬 l webman/workerman的协程基建套件及分享
Workerman实现Navicat Premium转发代理
主要用于代理MySQL连接,用Navicat Premium直接连接数据库,用不了一会在卡住,用了这个代理就可以流畅使用,也可以用于访问内部数据库或者服务等等。
Tinywan
2024/06/04
1330
Workerman实现Navicat Premium转发代理
Thinkphp8.0和Workerman5.0如何实现一对一聊天
Tinywan
2025/02/19
1890
Thinkphp8.0和Workerman5.0如何实现一对一聊天
windows 系统下 workerman 在同一个运行窗口中开启多个 websocket 服务
🎈 开启多个 ws 服务失败正常情况下,如果你想开启多个 websocket服务的话只要在一个文件中,输入 new Worker 两次,监听不同端口,使用 Worker::runAll() 命令即可但是你会发现在在 windows 中无法在一个文件中同时监听两个 websocket 服务,其他系统比如 Linux 是没有问题的会报 multi workers init in one php file are not support 错误,意思 windows 中禁止在同一个文件中开启多个 websocket
江户川码农
2023/03/17
1.6K2
windows 系统下 workerman 在同一个运行窗口中开启多个 websocket 服务
Laravel中Websocket基本使用(Workerman)
本文介绍workerman实现socket通讯,在此之前请确定你对websocket有所了解
切图仔
2022/09/14
3.2K0
Laravel中Websocket基本使用(Workerman)
高性能PHP框架webman服务端实现流式输出有哪些解决方案?
Stream流式输出是一种数据处理方式,它将数据以流的形式进行传输和处理。在这种处理方式中,数据不再是集中存储在某个地方,而是以分散的方式存储在各个节点上,并不断流动。数据流的处理是在流动的过程中完成的,因此能够实时地处理数据,提高了数据处理效率。
Tinywan
2024/11/21
3030
高性能PHP框架webman服务端实现流式输出有哪些解决方案?
视频教程 | Workerman基础教程-Worker类的使用
Workerman不是重复造轮子,它不是一个MVC框架,而是一个更底层更通用的服务框架,你可以用它开发tcp代理、梯子代理、做游戏服务器、邮件服务器、ftp服务器、甚至开发一个php版本的redis、php版本的数据库、php版本的nginx、php版本的php-fpm等等。Workerman可以说是PHP领域的一次创新,让开发者彻底摆脱了PHP只能做WEB的束缚。
Tinywan
2024/02/21
2190
视频教程 | Workerman基础教程-Worker类的使用
TP中利用workman获取实时数据
最新在项目当中需要实现数据的实时更新,于是利用workman简单的实现了对数据的实时获取。
北溟有鱼QAQ
2019/12/18
2.3K0
推荐阅读
相关推荐
PHP实现Workerman实例 高性能PHP Socket即时通讯框架
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验