php - swoole 异步task模式下,客户端如何知道该什么时候接收服务端发送的数据?

 

问题描述:

服务端代码:

<?php
        $serv = new \Swoole\Server('127.0.0.1', 9501);

        //设置异步任务的工作进程数量。
        $serv->set([
            'task_worker_num' => 4,
            // 'open_eof_split' => true,
            // 'package_eof' => "|||"
        ]);

        //此回调函数在worker进程中执行。
        $serv->on('Receive', function($serv, $fd, $reactor_id, $data) {
            // echo ' [ '.$reactor_id.' ]'.$data;
            $data = json_decode($data, true);
            print_r($data['content'] );
            foreach($data['content'] as $name => $sql){
                $serv->task(json_encode([$name => $sql]));
            }


            //投递异步任务
            // $task_id = $serv->task($data);
            // echo "Receive: Dispatch AsyncTask: id={$task_id}\n";
        });

        //处理异步任务(此回调函数在task进程中执行)。
        $serv->on('Task', function ($serv, $task_id, $reactor_id, $data) {
            $data = json_decode($data, true);
            foreach($data as $name => $sql){
                // print_r($data);
                // echo '['.$task_id.' task start '. microtime(true).'] ';  
                $res = Db::query($sql);
                // echo '['.$task_id.' task end '.microtime(true).' ]';
                print_r($res);

                echo '|'.$reactor_id.'|';
                $serv->send( $reactor_id, json_encode([$name => $res]));
                $serv->finish(json_encode([$name => $res]));
            }
            
            //返回任务执行的结果
            // $serv->finish("{$data}->OK1");ss
        });

        //处理异步任务的结果(此回调函数在worker进程中执行)。
        $serv->on('Finish', function ($serv, $task_id, $data) {
            // echo "Finish: AsyncTask[{$task_id}] Finish: {$data}".PHP_EOL;
            // $serv->send($task_id, 'PONG!!!');
        });

        $serv->start();
    
}

客户端代码:

<?php

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, -1)) {
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");
echo $client->recv();
$client->close();

在服务端代码中,由于向task中添加的任务执行时间不固定,所以如果早于服务端recv数据,就会报错,这个问题可以如何解决呢?


 

第 1 个答案:

<?php

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, -1)) {
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");

while (true) {
    $data = $client->recv();
    if (empty($data)) {
        break;
    }
    echo $data;
}

$client->close();
方法二:
用Swoole支持协程

dolphindb目前使用的 是pool = ddb.DBConnectionPool("0.0.0.0", 8903, 20, "admin", "123456")appender = ...