美文网首页
Swoole入门 - 异步 Task

Swoole入门 - 异步 Task

作者: 铁匠简记 | 来源:发表于2019-06-03 00:09 被阅读0次

    在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件、短信。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。
    Swoole提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。

    实现

    基于第一个WS服务器,只需要增加onTask和onFinish 2个事件回调函数即可,onFinish事件接收onTask事件执行完毕后的返回值。另外需要设置task进程数量,可以根据任务的耗时和任务量配置适量的task进程。

    场景

    当收到来自客户端的消息,执行一个耗时10秒的代码逻辑(如发送邮件),再去返回客户端消息,这个时候客户端就需要等待至少10秒,用户体验是非常差的。
    onTask事件的编写,我们可以查看官方文档


    <?php
    class WS {
        public $server;
        public function __construct() {
            $this->server = new Swoole\WebSocket\Server('0.0.0.0', 8812);
            $this->server->set([
                    'worker_num' => 2,
                    'task_worker_num' => 2
            ]);
            $this->server->on('open', [$this, 'onOpen']);
            $this->server->on('message', [$this, 'onMessage']);
            $this->server->on('task', [$this, 'onTask']);
            $this->server->on('finish', [$this, 'onFinish']);
            $this->server->on('close', [$this, 'onClose']);
    
            $this->server->start();
        }
    
        public function onOpen($server,$request)
        {
            echo "server: handshake success with fd{$request->fd}\n";
            // todo 10s
            $data = [
                    'task' => 1,
                    'fd'   => $request->fd
            ];
            $server->task($data);
            $server->push($request->fd,'server-push:'.date('Y-m-d H:i:s'));
        }
    
        public function onMessage($server,$frame)
        {
            echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
            $server->push($frame->fd, "this is server");
        }
    
        public function onTask($server, $taskId, $workerId, $data)
        {
            print_r($data);
            // 耗时场景 10s
            sleep(10);
            return 'on task 10s finish';   // 告诉worker
        }
    
        public function onFinish($server, $taskId, $data)
        {
            echo "taskId:{$taskId}\n";
            echo "finish-data-success:{$data}\n"
        }
    
        public function onClose($server,$fd)
        {
            echo "client {$fd} closed\n";
        }
    }
    $obj = new WS();
    

    测试

    开启http服务,ws服务。

    开启HTTP服务
    开启WebSocket服务
    浏览器访问http://127.0.0.1:8811/ws_client.html。通过HTTP服务启动ws客户端连接WebSocket服务,进入浏览器控制台可以看到,onFinish中的逻辑是在最后执行的,而在onOpen事件中,在投递task任务之后的逻辑并没有等Task的逻辑执行完再执行,这是因为Swoole的Task是异步处理的。
    用ws.html调起ws客户端 10s逻辑执行中
    10s逻辑执行完

    HTTP服务,TCP都是可以基于这种形式做Task任务投放的。

    相关文章

      网友评论

          本文标题:Swoole入门 - 异步 Task

          本文链接:https://www.haomeiwen.com/subject/xvnfxctx.html