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
即可测试成功