Code前端首页关于Code前端联系我们

什么是协程? swole完美支持TP5

terry 2年前 (2023-09-24) 阅读数 65 #后端开发

什么是协程?

协程可以被认为是纯粹的用户态线程,通过协作而不是抢占来切换。与 于进程 或线程相比,所有协程操作都可以在用户模式下执行。完成、创建和转换的消耗较低。 Swole可以为每个请求创建对应的协程,并根据IO状态合理调度协程。

在Swoole 4.x中,协程取代了异步回调,成为Swoole官方推荐的编程方式。 Swole协程解决了异步回调编程困难的问题。使用协程,可以用传统的同步编程方式编写代码,底层自动切换为异步IO,既保证了编程的简单性,又提高了使用异步IO的系统的并发性。技能。 完美支持TP5,首先启用Swoole的http服务

启用Swoole的http服务并在URL访问页面设置指定文件的根目录,

代码如下。这样浏览器只能访问...static下的文件,而不能访问其他文件夹下的文件。

http.server


//开启http server
$http = new swoole_http_server("0.0.0.0", 9905);
$http->set(
    [
        'enable_static_handler' => true,
        'document_root' => "/usr/local/openresty/nginx/html/swoole/LiveRadio/public/static",
        'worker_num' => 5
    ]
);
$http->on('request', function($request, $response) {
    $response->end("sss". json_encode($request->get));
});

$http->start();

swoole 有一个事件回调函数onWorkStart,该函数在工作进程/任务进程启动时发生。此处创建的对象可以在流程生命周期中使用。
原型:

function onWorkerStart(swoole_server $server, int workerid);

(1) onWorkerStart/onStart同时执行,没有先后顺序;

(2)可以通过服务器->任务工作者根据属性评估当前是工作进程还是任务进程?

(3) 当 worker_numtask_worker_num 大于 1 时,每个进程被触发一次 onWorkerStart Even t, 不同的工作流程可以通过以下方式区分关于 $employee_id 的判断;

(4) 进程worker向进程tasktask进程处理完所有任务后,设置工人 通过回调函数 onFinish 进行处理。

例如,我们在后台向 100,000 个用户发送群组电子邮件通知。操作完成后,操作状态显示为正在发送。这时候我们就可以继续其他的活动了。群发邮件完成后,操作状态自动变为已发送。

onWorkerStart加载框架核心文件后:
(1)不需要在每次请求时都加载框架核心文件以提高性能;
(2) 可以在后续的回调事件中使用。继续使用框架的核心文件或类库。

项目文件夹中public文件夹中的index.php为输入文件。源码如下:


// [ 应用入口文件 ]
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';

这个文件加载...thinkphp/start.php',start.php加载了一个核心的base.php文件,所以我们需要将base.php文件加载到onWorkStart回调函数中。每个worker进程都会触发一个onWorkerStart事件,以便ThinkPHP框架中的输入文件和其他内容可以加载到我们的项目中。

修改http.server如下:


//开启http server
$http = new swoole_http_server("0.0.0.0", 9906);
$http->set(
    [
        'enable_static_handler' => true,
        'document_root' => "/usr/local/openresty/nginx/html/swoole/LiveRadio/public/static",
        'worker_num' => 5  //设置worker进程数
    ]
);

$http->on('WorkerStart', function (swoole_server $server, $worker_id){
    //定义应用目录
    define('APP_PATH', __DIR__ . '/../application/');
    // 加载基础文件
    //这里不直接加载start.php的原因是start.php中的代码会直接执行,也就是application\index\controller\Index.php文件(框架的默认首页)
    /*
     * Container::get('app', [defined('APP_PATH') ? APP_PATH : ''])
    ->run()
    ->send();
    */
    require __DIR__ . '/../thinkphp/base.php';
});

$http->on('request', function($request, $response){
    //适配
    /*
     *由于swoole http提供的API和原生php代码是有所不同的,比如原生php中获取get参数为直接从全局数组_GET中获取,而swoole http中是通过$request->get()的方式获取,因此要转换成原生的
     * */

    $_SERVER = [];
    if(isset($request->server)){
        foreach($request->header as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }
    $_GET = [];
    if(isset($request->get)){
        foreach($request->get as $k => $v){
            $_GET[$k] = $v;
        }
    }
    $_POST = [];
    if(isset($request->post)){
        foreach($request->post as $k => $v){
            $_POST[$k] = $v;
        }
    }

    //..其余参数用到的继续往后写

    ob_start();
    // 执行应用并响应
    try {
        think\Container::get('app', [APP_PATH])
            ->run()
            ->send();
    }catch (\Exception $e){
        //todo
    }
    $res = ob_get_contents();
    ob_end_clean();
    $response->end($res);
});

$http->start();

现在使用浏览器访问http://ip:port/?s=index/index/index可以看到ThinkPHP的默认主页,但发现页面http://ip:port/?s=index/index/hello?name=world无法访问。

您可以打印和查看路线。在项目文件夹下的文件\thinkphp\library\think\App.php中,打印接口routeCheck中的路径变量。可以看到,URL改变后,path变量并没有改变。这是因为加载框架时,进程onWorkerStart会重用类成员变量。

    /**
     * URL路由检测(根据PATH_INFO)
     * @access public
     * @return Dispatch
     */
    public function routeCheck()
    {
        $path = $this->request->path();
        echo "path:".$path."
";
//        var_dump($this->request);
        $depr = $this->config('app.pathinfo_depr');

        // 路由检测
        $files = scandir($this->routePath);
        foreach ($files as $file) {
            if (strpos($file, '.php')) {
                $filename = $this->routePath . DIRECTORY_SEPARATOR . $file;
                // 导入路由配置
                $rules = include $filename;
                if (is_array($rules)) {
                    $this->route->import($rules);
                }
            }
        }

        // 是否强制路由模式
        $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');

        // 路由检测 返回一个Dispatch对象
        return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match'));
    }

更改:

进入项目文件夹\thinkphp\library\think\Request.php

(1)找到函数path(){ },退出判断,停止使用类成员变量$这个->路径。

(2)找到pathinfo(){ }函数,取消审核,停止使用类成员变量$this->pathinfo。

(3) 要支持pathinfo路由,请在pathinfo()函数中添加代码 { }

if (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != '/') {
    return ltrim($_SERVER['PATH_INFO'], '/');
}
协程是什么?swoole完美支持TP5

现在用浏览器打开:协程是什么?swoole完美支持TP5协程是什么?swoole完美支持TP5

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门