当前位置: 首页 > 知识库问答 >
问题:

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

武睿
2023-07-04

服务端代码:

<?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个答案

颜黎昕
2023-07-04
<?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支持协程
 类似资料:
  • 异步Mysql客户端 AsyncMysql::query($sql, $usePool = true) 第二个参数设为false将不会使用连接池中的资源,默认都会从连接池中取,配置连接池数量 => config/database.php 具体使用 use AsyncMysql; //设置超时时间 AsyncMysql::setTimeout(2); $res = (

  • 异步Redis客户端 连接池(连接池默认开启) use AsyncRedis; //关闭连接池 AsyncRedis::enablePool(false); //开启连接池 AsyncRedis::enablePool(true); 使用AsyncRedis use AsyncRedis; //设置超时时间 AsyncRedis::s

  • 异步Http客户端 Get方式 1.使用域名形式 use AsyncHttp; //直接使用域名, get方式 $http = new AsyncHttp('http://groupco.com'); //设置2s超时 $http->setTimeout(2); //$http->setCookies(['token' => 'xxxx']);

  • 异步Tcp客户端 串行发包 use AsyncTcp; $tcp = new AsyncTcp('127.0.0.1', 9501); $tcp->setTimeout(2); //串行发送 $res = (yield $tcp->call('hello server!')); $res = (yield $tcp->call('hello serv

  • 看起来它不应该那样工作。我在发送第一个数据包(大小为10字节,每次线性增加10字节)后启动时钟(在客户端),并在发送最后一个数据包后关闭时钟。 在服务器端(数据包的接收者),我在收到第一个数据包后启动时钟,在收到最后一个数据包后停止。为什么发送时间比接收时间长? 客户端模型代码(UDP发送方) 以及UDP服务器(接收器)的代码 编译并运行服务器 编译并运行服务器 样本结果: 客户(发送方) 服务器