編程學習網 > PHP技術 > swoole > Swoole教程案例分享之異步 Task
2021
05-31

Swoole教程案例分享之異步 Task

一、執行異步任務

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


Swoole提供了異步任務處理的功能,可以投遞一個異步任務到TaskWorker進程池中執行,不影響當前請求的處理速度。接下來就和大家分享一下swoole教程


如何使用:


onTask

onFinish

設置task_worker_num

二、代碼實現

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


我們可以使用上一節我們封裝的 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.html



<!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服務:



# php ws_task.php


然后在瀏覽器運行 ws_task_client.html 頁面:



這時我們再看服務端打印:



# 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才輸出來了。


以上就是本文的全部內容,如果覺得有用的話歡迎關注編程學習網,免費獲取資訊教程

掃碼二維碼 獲取免費視頻學習資料

Python編程學習

查 看2022高級編程視頻教程免費獲取