Swoole的Task使用以及swoole_client

2018-02-24 16:13 更新

環(huán)境說明: 系統(tǒng):Ubuntu14.04 (安裝教程包括CentOS6.5)
PHP版本:PHP-5.5.10
swoole版本:1.7.6-stable

上一章已經(jīng)簡單介紹了如何寫一個簡單的Echo服務(wù)器,并了解了onReceive等幾個核心回調(diào)函數(shù)的使用方法。這一章,我將介紹如何使用Swoole的異步任務(wù)Task。

1.Task簡介

Swoole的業(yè)務(wù)邏輯部分是同步阻塞運(yùn)行的,如果遇到一些耗時較大的操作,例如訪問數(shù)據(jù)庫、廣播消息等,就會影響服務(wù)器的響應(yīng)速度。因此Swoole提供了Task功能,將這些耗時操作放到另外的進(jìn)程去處理,當(dāng)前進(jìn)程繼續(xù)執(zhí)行后面的邏輯。

2.開啟Task功能

開啟Task功能只需要在swoole_server的配置項(xiàng)中添加task_worker_num一項(xiàng)即可,如下:

$serv->set(array(
    'task_worker_num' => 8
));

即可開啟task功能。此外,必須給swoole_server綁定兩個回調(diào)函數(shù):onTaskonFinish。這兩個回調(diào)函數(shù)分別用于執(zhí)行Task任務(wù)和處理Task任務(wù)的返回結(jié)果。

3.使用Task

首先是發(fā)起一個Task,代碼如下:

    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "Get Message From Client {$fd}:{$data}\n";
        // send a task to task worker.
        $param = array(
            'fd' => $fd
        );
        // start a task
        $serv->task( json_encode( $param ) );

        echo "Continue Handle Worker\n";
    }

可以看到,發(fā)起一個任務(wù)時,只需通過swoole_server對象調(diào)用task函數(shù)即可發(fā)起一個任務(wù)。swoole內(nèi)部會將這個請求投遞給task_worker,而當(dāng)前Worker進(jìn)程會繼續(xù)執(zhí)行。

當(dāng)一個任務(wù)發(fā)起后,task_worker進(jìn)程會響應(yīng)onTask回調(diào)函數(shù),如下:

    public function onTask($serv,$task_id,$from_id, $data) {
        echo "This Task {$task_id} from Worker {$from_id}\n";
        echo "Data: {$data}\n";
        for($i = 0 ; $i < 10 ; $i ++ ) {
            sleep(1);
            echo "Task {$task_id} Handle {$i} times...\n";
        }
        $fd = json_decode( $data , true )['fd'];
        $serv->send( $fd , "Data in Task {$task_id}");
        return "Task {$task_id}'s result";
    }

這里我用sleep函數(shù)和循環(huán)模擬了一個長耗時任務(wù)。在onTask回調(diào)中,我們通過task_id和from_id(也就是worker_id)來區(qū)分不同進(jìn)程投遞的不同task。當(dāng)一個task執(zhí)行結(jié)束后,通過return一個字符串將執(zhí)行結(jié)果返回給Worker進(jìn)程。Worker進(jìn)程將通過onFinish回調(diào)函數(shù)接收這個處理結(jié)果。

下面來看onFinish回調(diào):

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

onFinish回調(diào)中,會接收到Task任務(wù)的處理結(jié)果$data。在這里處理這個返回結(jié)果即可。 (Tip:?可以通過在傳遞的data中存放fd、buff等數(shù)據(jù),來延續(xù)投遞Task之前的工作)

點(diǎn)此查看完整示例

4.swoole_client

之所以在這里講解如何使用swoole_client是因?yàn)?,在寫服?wù)端代碼的時候,不可避免的需要用到客戶端來進(jìn)行測試。swoole提供了swoole_client用于編寫測試客戶端,下面我將講解如何使用這個工具。

swoole_client有兩種工作模式:同步阻塞模式和異步回調(diào)模式。其中,同步阻塞模式在上一章中已經(jīng)給出示例,其使用和一般的socket基本無異。因此,我將重點(diǎn)講解swoole_client的異步回調(diào)模式。

創(chuàng)建一個異步client的代碼如下:

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);

其中,SWOOLE_SOCK_ASYNC選項(xiàng)即表明創(chuàng)建一個異步client。

既然是異步,那當(dāng)然需要回調(diào)函數(shù)。swoole_client一共有四個回調(diào)函數(shù),如下:

$client->on("connect", function($cli) {
    $cli->send("hello world\n");
});
$client->on("receive", function($cli, $data){
    echo "Received: ".$data."\n";
});
$client->on("error", function($cli){
    echo "Connect failed\n";
});
$client->on("close", function($cli){
    echo "Connection close\n";
});

這幾個回調(diào)函數(shù)的作用基本和swoole_server類似,只有參數(shù)不同,因此不再贅述。?點(diǎn)此查看完整示例

進(jìn)階:簡易聊天室

我用swoole擴(kuò)展寫了一個簡單的聊天室Demo(點(diǎn)此查看) 這個Demo雖然用到了一些其他的架構(gòu),但是核心功能仍然是依托swoole擴(kuò)展實(shí)現(xiàn)的。

  • 通過onReceive回調(diào)接收數(shù)據(jù),根據(jù)預(yù)先規(guī)定的字段找到對應(yīng)的處理函數(shù)。
  • 通過onTask處理發(fā)送數(shù)據(jù)、廣播這樣的耗時內(nèi)容。

Server.php是全部的Swoole回調(diào)函數(shù)實(shí)現(xiàn)的類。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號