Swoole入门篇(下)
上一篇我们讲了如何安装Swoole
扩展,编写HTTP
服务器,编写WebSocket
服务器。这一章将会介绍Task
异步任务机制,以及Timer
定时器功能。
Task异步任务
Swoole Task:wiki.swoole.com/wiki/page/1…
为什么需要异步任务这种机制呢?
因为在某些场景之下,客户端是不需要关心服务器处理逻辑的,更需要的是实时的响应。比如一个实时的联机游戏,将游戏数据保存到MySQL
中就是一个耗时的操作,客户端并不需要知道保存的结果,需要的仅仅是游戏的数据。
如果按照普通的PHP Web
开发,每次请求的代码逻辑都是同步完成再进行响应,那游戏的延迟就会高到无法正常游玩。这时候就需要使用Task
这种异步任务的方式,让数据保存这种耗时任务交由另一个进程进行处理,服务端就能够立马响应客户端。
Task初始化
使用Task
需要在Server
创建的时候设置task_worker_num
属性,并且绑定onTask()
和onFinish()
方法。
做题时间
根据官方文档,在上一章的
WebSocket Server
代码的基础上,初始化Task
机制。<?php … class WebSocketServer {
...
public function __construct()
{
...
$this->server->set(array(
'worker_num' => 4,
'task_worker_num' => 4,
));
...
$this->server->on('task', [$this, 'onTask']);
$this->server->on('finish', [$this, 'onFinish']);
...
}
...
public function onMessage($server, $request)
{
...
$server->task('task_test');
}
...
public function onTask($server, $taskId, $srcWorkerId, $data)
{
echo "Tasker进程接收到数据" . PHP_EOL;
$i = 5;
while ($i--) {
sleep(1);
echo date('H:i:s') . PHP_EOL;
}
$server->finish($data);
}
public function onFinish($server, $taskId, $data)
{
echo "Task#$taskId finished, data_len=" . strlen($data) . PHP_EOL;
}
} …
代码的逻辑很简单,设置task_worker
为4个,当onMessage()
方法接收到消息后,投递一个task
任务并传入数据task_test
字符串。投递后将会触发Task Worker
回调onTask()
方法,在参数中会接收到$server
对象投递的task_test
字符串,连续5秒每秒会打印一次当前时间戳。当打印完毕后,调用$server
对象的finish()
方法,将数据返回到发起投递任务的主线程worker
。
打开chrome
开发者工具,查看network
标签。
这里显示了我们的服务端返回数据时间为23:48:10,接下来查看我们的服务端输出。
server: handshake success with fd1
receive from 1:this is client,opcode:1,fin:1
Tasker进程接收到数据
23:48:11
23:48:12
23:48:13
23:48:14
23:48:15
Task#0 finished, data_len=9
可以看到,onTask()
方法输出的时间是从23:48:11
开始的,当输出完5次后,触发onFinish()
方法输出了data_len
。也就是说我们的Task
机制运行正常。
Timer定时器
Swoole Timer:wiki.swoole.com/wiki/page/4…
Swoole
框架为我们提供了两种定时器:循环定时器swoole_timer_tick
和一次性定时器swoole_timer_after
,基本能够满足大部分场景。
swoole_timer_tick
swoole_timer_tick
是循环定时器,会按照设置的间隔时间一直重复的调用回调函数。在某些游戏中,可以使用这个定时器一直进行快速循环计算,将最新的游戏数据发送给每一个客户端。
新建一个test.php
文件,在里面输入以下代码:
<?php
//每隔2000ms触发一次
swoole_timer_tick(2000, function ($timer_id) {
echo time() . PHP_EOL;
});
运行效果:
[root@localhost PHPDemo]# php test.php
1560955350
1560955352
1560955354
1560955356
...
程序将会每隔两秒进行一次输出。
swoole_timer_after
swoole_timer_after
是一次性定时器,会进行等待设定好的时间间隔,触发一次回调函数。在某些游戏中,可以使用这个定时器做到游戏单局时长限制,触发定时器来结束一局游戏。
在test.php
文件中输入以下代码:
<?php
//3000ms后执行此函数
swoole_timer_after(3000, function () {
echo "after 3000ms.\n";
});
运行效果:
[root@localhost PHPDemo]# php test.php
after 3000ms.
[root@localhost PHPDemo]#
程序会在3秒后进行一次输出操作。
小结
Swoole
入门篇到这里就结束了,篇幅较少是因为小册目前只使用了这些技术,看上去也不是太难对吧?Swoole
还有许多例如协程、异步MySQL、异步Redis等技术等着你去学习。
仅仅学习入门篇的Demo写法是远远不够的,只有做项目写代码才能更深入的理解技术的使用方法,更多关于Swoole
的内容就请童鞋们在游戏开发篇章中进行学习了。