swoole异步任务池实现

swoole异步任务池实现

呀,第一次写博客文章,体谅一下。而且这篇文章不是为了记录是为了让你们挑我毛病(滑稽)。
正在学swoole,但是没在实战使用过 一直在自己尝试 肯定有错误 你们提出来我会改的
这篇是基于swoole文档的内容扩展成任务池,任务可扩展

异步任务池实现思路

首先基于tcp服务增加onTask和onFinish事件回调函数
onTask回调函数中执行异步任务,onFinish为任务完成后的回调函数

首先先做一个简易的tcp服务

<?php
class Server{
    public $serv;
    public function __construct()
    {

        $this->serv=new swoole_server('0.0.0.0',9501);
        $this->serv->on('Start',[$this,'onStart']);
        $this->serv->on('Receive',[$this,'onReceive']);
        $this->serv->on('Close',[$this,'onClose']);
        $this->serv->start();
    }

    #监听链接回调函数
    public function onStart(){
        echo "swoole 异步任务服务启动成功".PHP_EOL;
    }

    #监听数据接收回调函数
    public function onReceive($serv,$fd,$from_id,$data){
        echo "接收到客户端信息".PHP_EOL;
        print_r($data);
    }

    #客户端断开连接回调函数
    public function onClose($serv,$fd){
        echo "client-{$fd} :CLOSE".PHP_EOL;
    }

}
new Server();

基于tcp服务加上onTask 和 onFinish回调函数

服务端代码:Server.php

<?php
class Server{
    public $serv;
    public function __construct()
    {
        $this->serv=new swoole_server('0.0.0.0',9501);
        $this->serv->set([
            'task_worker_num'=>4#任务池数量
        ]);
        $this->serv->on('Start',[$this,'onStart']);
        $this->serv->on('Receive',[$this,'onReceive']);
        $this->serv->on('Task',[$this,'onTask']);
        $this->serv->on('Finish',[$this,'onFinish']);
        $this->serv->start();
    }

    public function onStart(){
        echo "swoole 异步任务池服务启动成功".PHP_EOL;
    }

    public function onReceive($serv,$fd,$from_id,$data){
        $task_id=$serv->task($data);
        echo "投递任务 {$task_id} 成功".PHP_EOL;
    }
    public function onTask($serv,$task_id,$from_id,$data){
        echo "执行任务 {$task_id}".PHP_EOL;
        $msg=include $data.'.php';#根据需按过来的文件名称 执行相对于文件  实现多任务扩展
        $serv->finish($msg);
    }

    public function onFinish($serv,$task_id,$data){
        echo "任务 {$task_id} 执行完成,执行结果:{$data}".PHP_EOL;
    }
    #此文件函数可以适当加入记录日志操作
}
new Server();
?>

这里采用文件形式执行任务代码,将某一任务的代码放到新文件中,在我们客户端连接tcp的时候将我们写好的文件名称传给任务池服务端,服务端接收到文件名称会去执行此文件代码(格式自定),最好包含返回值

客户端连接tcp

执行函数进行发送要执行的文件名称到服务端

客户端代码:TaskClient.php

<?php
class TaskClient{
    public $client;
    public function __construct(){
        $this->client=new swoole_client(SWOOLE_SOCK_TCP);
    }
    public function runTask($filename){
        $this->client->connect('服务器ip',9501,1);#链接server
        $this->client->send($filename);#发送任务文件名称 此例子为sendEmail文件名称
        $result=$this->client->recv();
        $this->client->close();
        return $result;
    }
}
$client=new TaskClient();
$result=$client->runTask('sendEmail');#使用参数传递文件名称 客户端也可复用
echo json_encode($result);die;
?>

任务逻辑文件

此文件会被引入执行:sendEmail.php

<?php
#此段代码为任务逻辑  start
#由于邮箱较少   直接采用sql操作修改字段  10000条数据  循环去修改某字段模拟发送邮件操作
$db=new PDO('mysql:host=127.0.0.1;dbname=study', 'root', 'root');
$sql = "SELECT * FROM `test_user`";
$list = $db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$time = date('Y-m-d H:i:s');
$result = [];
foreach ($list as $v) {
    $sql = "UPDATE `test_user` SET `send_time`='{$time}' WHERE `id`={$v['id']}";
    $result[] = $db->exec($sql);
}
$result = array_filter($result);
if (count($result) == count($list)) {
    $msg = '全部完成';
} else {
    $msg = '部分完成,请排查';
}
#任务逻辑  end
#这里可以返回msg 也可以记录日志  异步任务一般时间较长 应该记录日志 
return $msg;
?>

作者:言成

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值