为了账号安全,请及时绑定邮箱和手机立即绑定

SWOOLE 从入门到放弃之写个小框架(十四)

标签:
PHP
public function onMessage( $server ,$frame ){
        foreach ($this->server->connections as $fd) {
            $this->server->push($fd, 'message');
        }
    }

小伙伴们,如果你们是以为我是直接在回调方法里实现批量回复,就如上代码那样来实现,那就没劲了。。。

我要写个简单的任务投递类来实现它。

首选,创建frame/Lib/Task.php,Task.php仍然是单例模式,这次稍有不同的是,在获取实例时给它传入了$server对象,它有对象了。。。Task.php除去获取实例方法外还有三个方法,第一个是delivery 投递任务方法,需传入class名称,function名,和params参数;第二个是调度任务,传入task_id,worker_id和data,它的主要作用是执行投递进来的任务,和Server中的回调onTask是一致的; 第三个是完成任务后的输出状态,和Server中的回调onFinish是一致的。同时,这个类是不能被继承的,你问我为什么要这么干,我是怕被破坏呀,而且就算你硬要继承,我这也不支持。。。
贴代码了,不要惊讶,它特别简单。

<?php
/**
 * Task类
 */
namespace Piz;

final class Task
{
    /**
     * 实例
     * @var object
     */
    private static $instance ;

    public $server ;

    private function __construct (){}

    final public static function get_instance(){
        if( is_null(self::$instance) ) {
            self::$instance = new self();

        }
        return self::$instance;
    }

    final public function set_server($server){
        self::$instance->server = $server;
        return self::$instance;
    }

    /**投递任务
     * @param $class        \app\task\classname
     * @param $func
     * @param $params       []
     *
     * @return swoole_server->task_id
     */
    final public function delivery($class,$func,$params=[]){
        $task_id =  $this->server->task([$class,$func,$params]);
        echo "投递任务","\t","TaskID:{$task_id},","Class:{$class}","Func:{$func}","Params:".join (",",$params),PHP_EOL;
        return $task_id;
    }

    /**
     * 调度任务
     */
    final public function dispatch($task_id,$workder_id,$data){
        $ret = NULL ;
        if(empty($data)){
            echo "任务内容不合法","\t","TaskID:{$task_id}","任务内容不合法,必须传递数据,格式 [classname,function,params]",PHP_EOL;
            return FALSE;
        }
        list($classname , $func,$params) = $data ;
        try{
            $class =  (new $classname);
            $class->server = $this->server;
            return $class->$func(...$params);
        }catch (\Exception $e){
            return $e->getMessage ();
        }
    }

    /**
     * 完成任务
     */
    final public function finish($task_id,$data){
        echo "TaskID:{$task_id}\t{$data}",PHP_EOL;
    }

    public function __get($name){
        return $this->$name;
    }
}

怎么样,简单吧,我估计小伙伴们一下就明白了吧。。

接下来就是要把它和小框架接合起来。首先,我们修改App->websocket方法,在self::$map[$classname]->$action();上边增加一行代码self::$map[$classname]->task = Task::get_instance()->set_server ($server);,那它就被接入到了控制器了,在控制器里就能直接调用delivery方法了。

然后我们再修改一下Server.php 的代码,把 onTask和onFinish替换成下面的代码。

public function onTask($server,$task_id,$workder_id,$data){
        return Task::get_instance()->set_server ($server)->dispatch ($task_id,$workder_id,$data);
    }

    public function onFinish($server,$task_id,$data){
        Task::get_instance()->set_server ($server)->finish($task_id,$data);
    }

这还不算完,接下来,我要在app/task/目录下创建一个Notice.php通知类,类里面只有一个方法ToAll,代码如下

<?php
/**
 * 通知任务类
 */
namespace app\task;
class Notice{
    /**
     * 通知所有在线的客户端
     * @param $fd       发起请求的FD
     * @param $data     要发送的内容
     *
     * @return bool
     */
    public function ToAll($fd,$data){
        $fds = [] ;
        foreach($this->server->connections as $client_fd){
            if($fd != $client_fd && $this->server->exist($client_fd)){
                $this->server->push($client_fd,$data);
                $fds[] = $client_fd;
            }
        }
        return "已向[".join(",",$fds)."]发送通知内容:".$data;
    }
}

这个也很简单吧。

接下来,我们来改造一下app\modules/user/info.php里的get方法,代码

<?php
namespace app\modules\user;
class info
{
    public function get(){
        $content = "FD:{$this->fd};say:{$this->param['msg']}";
        $this->task->delivery (\app\task\Notice::class,'ToAll',[$this->fd,$content]);
    }
}

启动start.php 查看运行效果

图片描述

OK,行了。。。
小伙伴们,Task.php,我只是做了个简单实现,大家可以在此基础上随便扩展。。

代码已经传到码云上了,请移步 https://gitee.com/pizzzz/piz.git

下一篇,给它搞一个控制器父类吧,有些事不该省的就一定不能省。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
77
获赞与收藏
47

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消