swoole之任务和定时器
一、代码
<?php use Swoole\Server; /**
* 面向对象的形式 + task + timer
*/
class WebSocket
{
public $server; public function __construct()
{
$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$this->server->set([
'worker_num' => 2,
'task_worker_num' => 2
]);
// 注册事件回调
$this->server->on('open', [$this, 'onOpen']);
$this->server->on('message', [$this, 'onMessage']);
$this->server->on('task', [$this, 'onTask']);
$this->server->on('finish', [$this, 'onFinish']);
$this->server->on('close', [$this, 'onClose']);
} public function run()
{
$this->server->start();
} public function onOpen(Server $server, $request)
{
echo "server: handshake success with fd{$request->fd}" . PHP_EOL;
} /**
* 监听我是消息事件
* @param \Swoole\WebSocket\Server $server
* @param \Swoole\Websocket\Frame $frame 包含了客户端发来的数据帧信息
*/
public function onMessage(Swoole\WebSocket\Server $server, Swoole\Websocket\Frame $frame)
{
echo "receive from {$frame->fd}:{$frame->data}, opcode:{$frame->opcode}, fin:{$frame->finish}" . PHP_EOL; $data = [
'task' => 1,
'fd' => $frame->fd,
];
// 投放一个 异步 onTask任务
$server->task($data); if ($frame->fd == 1) {
$times = 3;
// 开始一个定时任务 每隔2s执行
swoole_timer_tick(2000, function ($timerId) use ($server, $frame, &$times) {
if ($times > 0) {
echo '1s: timerId:' . $timerId . PHP_EOL;
$times--;
} else {
swoole_timer_clear($timerId);
$server->push($frame->fd, 'timer tick over');
}
});
} // 指定的时间后执行 比下面的push后执行(异步)10s
swoole_timer_after(10000, function () use ($server, $frame) {
$server->push($frame->fd, "task finished " . date('Y-m-d H:i:s'));
}); // 不会堵塞 返回给客户端信息
$server->push($frame->fd, "服务器返回数据");
} /**
* 处理一些耗时的任务
* @param Server $serv
* @param int $taskId 任务ID
* @param int $srcWorkerId 来自于哪个worker进程
* @param mixed $data 异步投递的数据 任务的内容
* @return string
*/
public function onTask(Server $serv, $taskId, $srcWorkerId, $data)
{
// 处理一些耗时的任务
// print_r($data);
sleep(10);
if (isset($data['fd'])) {
$serv->push($data['fd'], 'task start:' . date("Y-m-d H:i:s"));
} // onFinsh 告诉worker进程
return "我是任务处理完后回调" . PHP_EOL;
} /**
* 任务处理完后执行
* @param Server $serv
* @param int $taskId
* @param string $data onTask返回的内容
*/
public function onFinish(Server $serv, $taskId, $data)
{
echo 'taskId:' . $taskId . ' && task finished && data is ' . $data;
} /**
* TCP客户端连接关闭
* @param Server $ser
* @param int $fd
* @param int $reactorId 来自那个reactor线程
*/
public function onClose(Server $ser, $fd, $reactorId)
{
echo "client {$fd} closed\n";
}
} $server = new WebSocket();
$server->run();
客户端用的还是原来的 ws_client.html
服务器输出:
文档: https://wiki.swoole.com/wiki/page/397.html
swoole之任务和定时器的更多相关文章
- RabbitMQ 入门教程(PHP版) 延迟队列,延迟任务
延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...
- 如何使用 Workman 做一个聊天室
一:首先,得简单说说 thinkphp+workerman 的安装. 安装 thinkphp5.1 composer create-project topthink/think=5.1.x-dev t ...
- PHP框架Swoole的一个定时器Timer特性
在各种业务型系统中,往往需要服务器在后台扫描相关数据,触发相应的统计.通知等操作. 比如对于一个项目管理系统,需要每天的特定时间内,统计每项任务的执行.到期情况.整个项目的进度等等,根据统计情况,做相 ...
- 【swoole】如果使用好定时器功能
swoole中提供了一个定期器的用法 $server->tick(1000, function() use ($server, $fd) { $server->send($fd, &quo ...
- 关于swoole 定时器有时候无法清除的解决方法
关于swoole 定时器有时候无法清除的解决方法 有时候start里面写个定时器 有时候你关闭进程的时候 发现定时器还是可以进行 目前只有重启服务器才可以 清除 还有就是ps -ef | grep p ...
- Swoole 中毫秒定时器(Timer)的使用
间隔定时器, tick 定时器会持续触发,直到调用 clear() 清除为止. $timer = Swoole\Timer::tick(3000, function (int $timer_id, $ ...
- Swoole学习(六)Swoole之定时器的创建与清除
环境:Centos6.4,PHP环境:PHP7,Swoole2.1(在指定的时间后执行函数,需要1.7.7或更高版本) <?php //----------------------------- ...
- swoole 清除定时器提示no timer
首页确定一个核心概念 clearTimer仅可清除当前进程的定时器 server代码如下: <?php class Server { private $serv; private $timer; ...
- swoole 定时器 swoole_time_tick 和 swoole_time_after
<?php class myticker{ public $server = null; CONST host = '127.0.0.1'; CONST port = 9502; public ...
随机推荐
- VUE 鼠标右键自定义
需要在区域内右击自定义菜单的DIV绑定contextmenu右击事件 <div style="width:100% ; z-index: inherit;position: rel ...
- floyd的魔改应用——洛谷P2419 [USACO08JAN]牛大赛Cow Contest 题解
想找原题请点击这里:传送门 原题: 题目背景 [Usaco2008 Jan] 题目描述 N ( ≤ N ≤ ) cows, conveniently numbered ..N, are partici ...
- Nginx 反向代理报400错误解决方法!
如果后端真是的服务器设置有类似防盗链或者根据http请求头中的host字段来进行路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败,报400错误,解决办法: ...
- 区分git ,github,github桌面版,gitbash、gitshell
推荐链接:https://www.runoob.com/git/git-tutorial.html https://www.zhihu.com/question/34582452?sort=c ...
- 区间树Splay——[NOI2005]维护数列
无指针Splay超详细讲解 区间树这玩意真TM玄学. 学这东西你必须要拥有的 1.通过[模板]文艺平衡树(Splay),[模板]普通平衡树,GSS3 - Can you answer these qu ...
- Java 中 VO、PO、DTO、BO、POJO、DAO 之间的区别与解释
转载:https://www.cnblogs.com/hunmeng/p/11298680.html VO value object:值对象 通常用于业务层之间的数据传递,由new创建,由GC回收. ...
- 汇编语言从入门到精通-5微机CPU的指令系统1
微机CPU的指令系统 5.1 汇编语言指令格式 为了介绍指令系统中指令的功能,先要清楚汇编语言是如何书写指令的,这就象在学习高级语言程序设计时,要清楚高级语言语句的语义.语法及其相关规定一样. 5.1 ...
- (未解决)flume监控目录,抓取文件内容推送给kafka,报错
flume监控目录,抓取文件内容推送给kafka,报错: /export/datas/destFile/220104_YT1013_8c5f13f33c299316c6720cc51f94f7a0_2 ...
- java 中类加载器
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式. java 中类加载器分为三个: BootstrapClassLoader 负责加载 ${ ...
- Python 之网络编程之socket(1)TCP 方式与UDP方式
一:socket介绍 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API) ...