swoole 执行异步任务 (Task)+客户端的调用

swoole 执行异步任务 (Task)+客户端的调用

目录结构

在这里插入图片描述

服务端的实现

task_server.php

<?php
 use Swoole\Coroutine;
 use function Swoole\Coroutine\run;

$serv = new Swoole\Server('0.0.0.0', 9501);

//设置异步任务的工作进程数量
$serv->set([
    'task_worker_num' => 4,
    'max_wait_time' => 60,
    //实现异步安全重启
    'reload_async' => true,
]);

//监听连接进入事件
$serv->on('Connect', function ($server, $fd) {
    
    
    echo "Client: 用户{
      
      $fd}进入房间.\n";
});
 
//此回调函数在worker进程中执行
$serv->on('Receive', function($serv, $fd, $reactor_id, $data) {
    
    
    //投递异步任务
    $task_id = $serv->task($data);
    echo "任务调度: id={
      
      $task_id}\n";
});
 
//处理异步任务(此回调函数在task进程中执行)
$serv->on('Task', function ($serv, $task_id, $reactor_id, $data) {
    
    
    echo "任务[id={
      
      $task_id}]".PHP_EOL;
    // 等待10秒
    sleep(10);
    // 模拟异常是否会阻塞其他用户的请求
    //throw new \Exception('Swoole Server does not connected.'); 
    //返回任务执行的结果
    $serv->finish("{
      
      $data} -> OK");
});
 
//处理异步任务的结果(此回调函数在worker进程中执行)
$serv->on('Finish', function ($serv, $task_id, $data) {
    
    
    echo "任务[{
      
      $task_id}] 完成: {
      
      $data}".PHP_EOL;
});
 
 
//监听连接关闭事件
$serv->on('Close', function ($server, $fd) {
    
    
    echo "Client: 用户{
      
      $fd}退出房间.\n";
});
 
$serv->start();

客户端的调用

Swooleclient.php

<?php
class SwooleClient
{
    
      
    private $client;

    public function __construct()  
    {
    
      
        $this->client = new \Swoole\Client(SWOOLE_SOCK_TCP);
    }  
  
    public function connect()  
    {
    
      
       //9501要和swoole服务监听的端口号一致
        if (!$this->client->connect("127.0.0.1", 9501, -1)) {
    
    
            throw new \Exception(sprintf('Swoole Error: %s', $this->client->errCode));
        }  
    }  
  
  //投递一个数据到swoole服务中
    public function send($data)  
    {
    
      
        if ($this->client->isConnected()) {
    
      
            if (!is_string($data)) {
    
      
                $data = json_encode($data);  
            }
          //拼接"\r\n",是解决在循环场景下,投递任务可能会出现的tcp粘包问题。
            return $this->client->send($data."\r\n");  
        } else {
    
      
            throw new \Exception('Swoole Server does not connected.');
        }  
    }  
  
    public function close()  
    {
    
      
        $this->client->close();  
    }  
} 

test_clinet.php

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require_once "./Swooleclient.php";
require '../vendor/autoload.php';

//在需要投递的场景时,new 一个客户端类,把数据投递到swoole服务中
$client = new Swooleclient();
$client->connect();
$code = mt_rand(1111,9999);
$phone_num = "12345678";
$task_data = [
    'method' => 'sendSms',
    'data'   => [
        'code'       => $code,
        'phone_num'  => $phone_num
    ]
];
//投递任务
if ($client->send(json_encode($task_data))) {
    
    
   //成功,关闭链接
        $client->close();
} else {
    
    
  //异常处理
}



$client1 = new Swooleclient();
$client1->connect();
$code1 = 200;
$phone_num1 = "66666666666666666";
$task_data = [
    'method' => 'sendSms',
    'data'   => [
        'code'       => $code1,
        'phone_num'  => $phone_num1
    ]
];
//投递任务
if ($client1->send(json_encode($task_data))) {
    
    
   //成功,关闭链接
        $client1->close();
} else {
    
    
  //异常处理
}

测试:

php test_clinet.php
php task_server.php
php Swooleclient.php

即可测试成功

在这里插入图片描述

通过postman模拟客户端请求服务端测试:

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sunrj_niu/article/details/129706522