<?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(); |
}); |
中级程序员
by: FN 发表于:2022-09-29 15:48:00 顶(2) | 踩(2) 回复
,...
回复评论