用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - php代码库

PHP+Swoole实现web版的shell客户端详解

2022-08-07 作者: 李浩举报

[php]代码库

<?php
 
include_once 'include/functions.php';
include_once 'vendor/autoload.php';
 
use swoole\http\request;
use swoole\http\response;
use swoole\websocket\closeframe;
use swoole\coroutine\http\server;
 
use swoole\coroutine;
use function swoole\coroutine\go;
use function swoole\coroutine\run;
use function swoole\coroutine\defer;
use phpseclib3\net\ssh2;
 
 
 
/*
 * 设置协程运行相关的参数
 * */
co::set([
    'socket_timeout'=>-1, //tcp超时
    'hook_flags' => swoole_hook_all  //hook函数范围
]);
 
 
/*
 * 创建协程容器
 * */
run(function () {
 
    /*
     * 第三个参数 代表是否开启ssl
     * */
    $server = new server('0.0.0.0', 5707, false);
 
    $server->handle('/ws', function (request $request, response $ws) {
 
        /*websocket协议*/
        $ws->upgrade();
 
        /*连接ssh*/
        $ssh = new ssh2('localhost',22);
 
        /*如果登录失败*/
        if (!$ssh->login('root', 'qq461625091@')) {
            $ws->close();
            return;
        }
 
        /*命令输出内容的读取时间*/
        $ssh->settimeout(0.1);
 
 
 
        /*
         * 创建协程,专门输出命令行内容
         * */
        $subscribe=function () use($ws,$ssh){
 
 
            /*
             * 保存id,用于取消协程
             * */
            $ws->gid = go(function () use ($ws,$ssh){
 
                /*
                 * 协程退出时清理
                 * */
                defer(function () use ($ssh,$ws) {
                    /*
                     * 退出
                     * */
                    logs($ws->qq.',已断开链接!');
                    $ssh->disconnect();
                });
 
 
                try {
 
                    while (true){
                        $msg=$ssh->read('username@username:~$');
                        if(!empty($msg)){
                            $ws->push($msg);
                        }
                    }
 
                } catch (\throwable $e) {
                    logs('读取异常');
                }
 
            });
        };
 
 
        /*
         * 清理
         * */
        $quit=function ($log) use ($ws){
 
            logs($log);//记录退出原因
 
            /*
             * 如果协程已经运行
             * */
            if(isset($ws->gid)){
                coroutine::cancel($ws->gid); //关闭协程
            }
 
            $ws->close(); //断开ws
 
        };
 
 
        /*
         * 正常处理逻辑
         * */
 
        $subscribe(); //开始订阅
 
        $cmd=[
            'ps -ef',
            'ping 127.0.0.1',
            'ifconfig',
            "\x03"
        ];
 
 
        while (true) {
 
            $frame = $ws->recv(); //阻塞接收消息
 
            if ($frame === '') {
 
                $quit("断开连接,收到空数据!");
                break;
 
            } else if ($frame === false) {
 
                $quit(swoole_last_error());
                break;
 
            } else {
 
                if ($frame->data == 'close' || get_class($frame) === closeframe::class) {
                    $quit("用户主动关闭\n");
                    break;
                }
 
                /*
                  * 如果不在测试命令,则终止
                  * */
                if(!in_array($frame->data,$cmd)){
                    continue;
                }
 
                $ssh->write($frame->data."\n"); // note the "\n"
 
            }
        }
    });
 
 
    /*
     * 输出默认测试模板
     * */
    $server->handle('/', function (request $request, response $response) {
        $response->end(gettest());
    });
 
    $server->start();
});


网友评论    (发表评论)

共1 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...