Swoole在Tp5.1中的使用,分发Task异步任务机制实现

浏览:452 发布日期:2019/01/10 分类:技术分享 关键字: swoole tp5
1. 面向过程方案<?php
/**
 * Created by PhpStorm.
 * User: baidu
 * Date: 18/2/28
 * Time: 上午1:39
 */
$http = new swoole_http_server("0.0.0.0", 9501);
 
$http->set([
    'worker_num' => 5,
]);
$http->on('WorkerStart', function(swoole_server $server,  $worker_id) {
    // 定义应用目录
    define('APP_PATH', __DIR__ . '/../../application/');
    // 加载框架里面的文件
    require __DIR__ . '/../base.php';
    //require __DIR__ . '/../thinkphp/start.php';
});
$http->on('request', function($request, $response) use($http){
 
    $_SERVER  =  [];
    if(isset($request->server)) {
        foreach($request->server as $k => $v) {
            $_SERVER[strtoupper($k)] = $v;
        }
    }
    if(isset($request->header)) {
        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();
    // 执行应用并响应
    think\Container::get('app', [APP_PATH])->run()->send();
    // echo "-action-".request()->action().PHP_EOL;
    $res = ob_get_contents();
    ob_end_clean();
    $response->end($res);
    // $http->close($http->fd);
});$http->start();


    onWorkerStart:

    此事件在Worker进程/Task进程启动时发生,这里创建的对象可以在进程生命周期内使用
    在onWorkerStart中加载框架的核心文件后:

不用每次请求都加载框架核心文件,提高性能
可以在后续的回调事件中继续使用框架的核心文件或者类库
结果展示:(监听9501端口,路由需要配置,暂时用s=url 的方式.)

分发Task异步任务机制实现<?php
 
/**
*     socket面向对象的编译
*/
class Ws
{
    CONST HOST='0.0.0.0';
    CONST PORT='9501';
    public $ws=null;
 
    public function __construct()
    {
        $this->ws=new swoole_http_server(self::HOST,self::PORT);
        $this->ws->set([
            //启动task必须要设置其数量
            'worker_num' => 4,
            'task_worker_num' => 4,
        ]);
        $this->ws->on('workerStart',[$this,'onWorkerStart']);
        $this->ws->on('request',[$this,'onRequest']);
        $this->ws->on('task',[$this,'onTask']);
        $this->ws->on('finish',[$this,'onFinish']);
        $this->ws->on('close',[$this,'onclose']);
        $this->ws->start();
    }
 
    /**
        监听开启事件的回调
    */
    public function onWorkerStart($server, $worker_id)
    {
        // 定义应用目录
        define('APP_PATH', __DIR__ . '/../application/');
        // 加载框架里面的文件
        require __DIR__ . '/../thinkphp/base.php';
    }
    
     /**
     * request回调
     * @param $request
     * @param $response
     */
    public function onRequest($request, $response) {
        $_SERVER  =  [];
        if(isset($request->server)) {
            foreach($request->server as $k => $v) {
                $_SERVER[strtoupper($k)] = $v;
            }
        }
        if(isset($request->header)) {
            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;
            }
        }
        $_POST['http_server'] = $this->ws;
 
        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);
    }
    /**
        监听关闭事件的回调
    */
    public function onclose($ser, $fd)
    {
        print_r("你好,我的{$fd}\n");
    }
 
    /**
    *    $serv             服务
    *    $task_id        任务ID,由swoole扩展内自动生成,用于区分不同的任务
    *    $src_worker_id     $task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
    *    $data             是任务的内容
    */
     public function onTask($serv,$task_id,$src_worker_id,$data)
    {
        //在终端输出
        print_r($data).'/n';
        //执行耗时任务
        sleep(10);
        //回调于onFinish
        return '你成了-A';
    }
    /**
    *    $task_id         是任务的ID
    *    $data            是任务处理的结果内容
    */
     public function onFinish($serv,$task_id,$data)
    {
        print_r($data).'/n';
    }
 
}
 
new Ws();
控制器中,千万不要再系统默认加载的控制器下写task,否则你就会发现多执行了一次任务,切记!?php
namespace app\index\controller;
 
class Index
{
    public function index()
    {
        $data='我是分发任务';
        $a=$_POST['http_server']->task($data);
        echo $a.PHP_EOL;
        return 123;
    }
 
    public function a()
    {
        $data='我是分发任务aaaaaa';
        $a=$_POST['http_server']->task($data);
        return 123456798;
    }
    public function bbb()
    {
        return 1111111111111111;
    }
}
结果展示:


到了这里很多朋友觉得swoole可能有点难以上手。Swoft微服务在用的过程中遇到很多问题,某些方面的知识存在不足,没关系,我为大家准备了一套精品PHP中高级进阶项目实战学习教程,需要加微信:PHPopen888,还可加入微信群,分享tp,laravel,swoole,swoft、分布式、高并发等实战教程,各种大牛都是3-8年PHP开发者,每天还有11年资深架构师的课程讲解,助你进阶中高级PHP程序员,增值涨薪!不想提升自己,不爱学习,不想涨薪的勿扰!





需要加微信:PHPopen888,还可加入微信群,分享tp,laravel,swoole,swoft、分布式、高并发等教程,各种大牛都是3-8年PHP开发者,每天还有11年资深架构师的课程讲解,助你进阶中高级PHP程序员,增值涨薪!
最佳答案
评论( 相关
后面还有条评论,点击查看>>