Swoole學習之Swoole Task任務(六)

1、執行異步任務

在Server程序中若是須要執行很耗時的操做,好比一個聊天服務器發送廣播,Web服務器中發送郵件。若是直接去執行這些函數就會阻塞當前進程,致使服務器響應變慢。php

Swoole提供了異步任務處理的功能,能夠投遞一個異步任務到TaskWorker進程池中執行,不影響當前請求的處理速度。html

如何使用:前端

  • onTask
  • onFinish
  • 設置task_worker_num

2、代碼實現

咱們看Swoole官方文檔入門指引->快速起步->Task執行異步任務web

咱們能夠使用上一節咱們封裝的 websocket類中使用:瀏覽器

ws_task.php服務器

<?php

/**
 * WS 優化基礎類庫
 */

class Ws
{
    public $ws = null;

    CONST HOST = "0.0.0.0";
    CONST PORT = 80;

    public function __construct()
    {
        // static::HOST, static::PORT
        $this->ws = new swoole_websocket_server("0.0.0.0", 80);

        $this->ws->set(
            [

               'enable_static_handler' => true, // 靜態資源相關設置
               'document_root' => "/work/study/code/swoole/demo/static", // 存放靜態資源路徑
               'worker_num' => 2,
               'task_worker_num' => 2,
            ]
        );

        $this->ws->on("open", [$this, "onOpen"]);
        $this->ws->on("message", [$this, "onMessage"]);
        $this->ws->on("task", [$this, "onTask"]);
        $this->ws->on("finish", [$this, "onFinish"]);
        $this->ws->on("close", [$this, "onClose"]);

        $this->ws->start();
    }

    /**
     * 監聽ws鏈接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        print_r("Open:" . $request->fd ."\n");
    }

    /**
     * 監聽ws鏈接消息
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame)
    {
        echo "ser-push-message:{$frame->data}\n";

        // TODO::加入咱們這個業務須要執行超過 10s,因此,這裏能夠使用task異步來處理
        $data = [
            'task' => 1,
            'fd' => $frame->fd,
        ];

        // 投遞一個任務
        $ws->task($data);
        $ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));

    }

    /**
     * 投遞任務
     *
     * @param $serv
     * @param $taskId
     * @param $workerId
     * @param $data
     */
    public function onTask($serv, $task_id, $from_id, $data)
    {
        // 耗時場景 10s
        sleep(10);

        return "on task finish";  // 告訴worker
    }

    public function onFinish($serv, $task_id, $data)
    {
        echo "taskId:{$task_id}\n";

        // 注意:此$data參數爲onTask方法返回的結果:on task finish,而不是onTask方法的參數。
        echo "finish-data-success:{$data}\n";

    }

    /**
     * 監聽WebSocket鏈接關閉事件
     *
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd)
    {
        echo "clientid-{$fd} is closed \n";
    }
}

$ws_obj = new Ws();

前端靜態頁面:
ws_task_client.htmlwebsocket

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket TEST</title>
</head>
<body>
<h1>Swoole-TEST</h1>
<script>
    var wsUrl = "ws://0.0.0.0:8880";
    var websocket = new WebSocket(wsUrl);

    // 實例化onopen對象
    websocket.onopen = function(evt){
        websocket.send("Hello-Lily"); // 發送信息給服務端
        console.log("connected-swoole-success")
    }

    // 實例化 onmessage
    websocket.onmessage = function(evt){
        console.log("ws-server-return-data"+evt.data)
    }

    // 實例化 onclose
    websocket.onclose = function(evt){
        console.log("close")
    }

    // onerror
    websocket.onerror = function (evt) {
        console.log("error:" + evt.data)
    }


</script>

</body>
</html>

咱們在先開啓websocket服務:swoole

# php ws_task.php

而後在瀏覽器運行 ws_task_client.html 頁面:異步

clipboard.png

這時咱們再看服務端打印:socket

# php ws_task.php
Open:3
ser-push-message:Hello-Lily
clientid-1 is closed
taskId:0
finish-data-success:on task finish

咱們能夠看出,頁面message及時響應,而在服務器端Task異步任務過了10s才輸出來了。

相關文章
相關標籤/搜索