• Thinkphp5 集成 Swoole


    Swoole简介

    Swoole是一个面向生产环境的 PHP 异步网络通信引擎。使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。

    Swoole扩展是按照PHP标准扩展构建的。使用phpize来生成编译检测脚本,./configure来做编译配置检测,make进行编译,make install进行安装。

    Swoole实际上是一个网络通信和异步io的引擎,一个基础库。php与外部通信需要借助系统的socket,通常使用的Apache nginx就是封装了的socket,可以实现并发处理。客户端发送请求到nginx/apache,再转发到fastcgi端口交给php处理;Swoole把系统的socket集成到php底层,php可以直接通过swoole与客户端交互。也就是说Swoole是个封装了底层socket的网络库,解决异步处理、长连接、并发处理任务等。

    Swoole与传统php开发的区别

    1.PHP的运行模式

    PHP有多种运行模式,常见的Fast-CGI,PHP-FPM模式我们归纳为传统的web模式,还有一种模式属于命令行模式:PHP-Cli

    2.Swoole开发的程序和传统的php程序区别

    因为使用swoole拓展的PHP脚本与传统的PHP脚步不同,前者是需要预先在服务端执行的,而后者是每次访问时才会执行。

    ① 比如你的程序中定义了一个类A,那么在每次有用户访问时,类A都需要提前编译到内存中,1万次访问就要编译1万次。而用swoole拓展则只需要在服务端编译一次,无论多少次访问都不需要再次编译了,只要swoole的进程存在,类A就会一直存在于内存中。

    ② 比如PHP入门时就必须要掌握的session,对于运用了swoole扩展的PHP程序而言,完全可以用一个变量来替换。

    ③ 平时写PHP代码,完全不必担心内存使用,全局变量/函数/对象等,可以随便使用,因为PHP脚本执行结束后,内存自然会自行释放掉。但用swoole扩展的PHP程序,则必然要手动注销全局的变量/函数/对象等,这就考验了PHPer的闭包能力等。

    Thinkphp5集成Swoole

    think-swoole2.0支持thinkphp5.0

    think-swoole3.0支持thinkphp6.0

    推出的tp6.0,已经适配swoole.并推出think-swoole 3.0,并且默认适配了socketio。和2.0版本在使用方法上面有些许不同。

    Websocket 继承于Http,进行websocket连接之前需要一次HTTP请求,如果当期地址支持websocket则返回101,然后进行连接。也就是说并不是我的服务支持websocket后,请求每个连接地址都可以进行websocket连接,而是需要预先适配才可以连接,tp提供的组件刚开始不建议使用,等自己写熟悉了后再研究。

    01

    TP5的运行机制

    任何请求都会经过tp5的入口文件,载入框架的配置文件,启动进程,然后处理请求。

    在这个index.php的入口文件中,可以看到,它先定义的APP_PATH这个常量,然后引入的框架的启动文件start.php,那我们就去看下start.php这个文件做了些什么。

    在这里,它先加载了基础文件base.php,然后启动框架run,这个时候就开始处理请求了。常规的nginx,Apache服务器,每次请求来到thinkphp,会清除静态变量,重新加载配置文件。但是Swoole做的服务器,是常驻进程,在启动服务后,会产生多个进程,来处理请求。我们要让它选择性的加载配置。

    02

    Swoole来做http服务器

    <?php
    /**
     * Created by PhpStorm.
     * User: 360zhiliangxiaoneng
     * Date: 2019/10/21
     * Time: 15:09
     */
    
    $http = new swoole_http_server("0.0.0.0", 9501);
    
    $http->set(
        [
            'enable_static_handler' => true,
            'document_root' => "/var/www/thinkphp_5.0.11/public/static",
            'worker_num' => 5,//产生进程的个数
        ]
    );
    
    $http->on('WorkerStart',function (swoole_server $server,$worker_id){
        define('APP_PATH', __DIR__ . '/../application/');
        // 这里 引入 base.php  而不引入start.php  是因为
        // start.php 的话 就会执行thinkphp 的相应的控制器方法了
        require __DIR__ . '/../thinkphp/base.php';
    });
    
    
    $http->on('request', function($request, $response) use($http) {
        $_SERVER=[];
    
        if(isset($request->header)){
            foreach ($request->header as $k=>$v){
                $_SERVER[strtoupper($k)] = $v;
            }
        }
        if(isset($request->server)){
            foreach ($request->server 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;
            }
        }
       // print_r($_SERVER);
    
        //开启缓存
        ob_start();
        try{
            // 执行应用并响应
            //think\Container::get('app', [APP_PATH])->run()->send();
            think\App::run()->send();
        }catch (\Exception $e){
    
        }
        $res = ob_get_contents();
        ob_end_clean();
        $response->header('Content-Type', 'text/html;charset=utf-8', false);
        $response->end($res);
        //$http->close();
    });
    $http->start();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    1. $http->onWorkerStart:启动进程的时候,加载thinkphp的框架文件,base.php,但是这个时候,不能run,等待请求来了再去run。

    2. KaTeX parse error: Expected 'EOF', got '&' at position 6: http-&̲gt;onrequest:当收…_SERVER,$_GET等信息,可以适配tp5。

    3. 最后开始run,这个时候需要把run得到的信息加载到缓存,然后再通过send()返回给客户端。

    03

    Swoole适配thinkphp5

    因为swoole是常驻进程,前一个请求的 P O S T , _POST, POST_GET请求不会销毁,原因这个进程并没有kill,这个时候,需要在接收请求的时候,将 G E T , _GET, GET,_POST置空。swoole路由机制,总会从缓存中获取有没有这个请求,如果有,就不加载新的,所以,swoole常驻内存,会发现一直请求第一个url。除非重启swoole服务器。

    在Thinkphp框架里面,修改Request文件,将两个方法(pathinfo,path)里面的$this->path这个为空的判断去掉,让每次请求都去解析这个url。

    更多技术文章

  • 相关阅读:
    哪款蓝牙耳机平价好用?值得学生党入手的蓝牙耳机推荐
    MySQL死锁举例及代码如何解决
    从数字化到智能化再到智慧化,智慧公厕让城市基础配套更“聪明”
    Qt的.pro文件格式解析
    matlab分岔图绘制
    Elasticsearch深入理解(十三)——Index更换字段类型的三种方式
    第八章:Springmvc中web.xml配置文件
    从零入门 Vite 与 Webpack 对比
    Python小波分析库pywt介绍
    Stable Diffusion - StableDiffusion WebUI 软件升级与扩展兼容
  • 原文地址:https://blog.csdn.net/Tester_muller/article/details/126514852