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

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是一致的。同时,这个类是不能被继承的,你问我为什么要这么干,我是怕被破坏呀,而且就算你硬要继承,我这也不支持。。。

贴代码了,不要惊讶,它特别简单。

/**

* 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,代码如下

/**

* 通知任务类

*/

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方法,代码

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 查看运行效果

AAffA0nNPuCLAAAAAElFTkSuQmCC

OK,行了。。。

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值