一、代码

<?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之任务和定时器的更多相关文章

  1. RabbitMQ 入门教程(PHP版) 延迟队列,延迟任务

    延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...

  2. 如何使用 Workman 做一个聊天室

    一:首先,得简单说说 thinkphp+workerman 的安装. 安装 thinkphp5.1 composer create-project topthink/think=5.1.x-dev t ...

  3. PHP框架Swoole的一个定时器Timer特性

    在各种业务型系统中,往往需要服务器在后台扫描相关数据,触发相应的统计.通知等操作. 比如对于一个项目管理系统,需要每天的特定时间内,统计每项任务的执行.到期情况.整个项目的进度等等,根据统计情况,做相 ...

  4. 【swoole】如果使用好定时器功能

    swoole中提供了一个定期器的用法 $server->tick(1000, function() use ($server, $fd) { $server->send($fd, &quo ...

  5. 关于swoole 定时器有时候无法清除的解决方法

    关于swoole 定时器有时候无法清除的解决方法 有时候start里面写个定时器 有时候你关闭进程的时候 发现定时器还是可以进行 目前只有重启服务器才可以 清除 还有就是ps -ef | grep p ...

  6. Swoole 中毫秒定时器(Timer)的使用

    间隔定时器, tick 定时器会持续触发,直到调用 clear() 清除为止. $timer = Swoole\Timer::tick(3000, function (int $timer_id, $ ...

  7. Swoole学习(六)Swoole之定时器的创建与清除

    环境:Centos6.4,PHP环境:PHP7,Swoole2.1(在指定的时间后执行函数,需要1.7.7或更高版本) <?php //----------------------------- ...

  8. swoole 清除定时器提示no timer

    首页确定一个核心概念 clearTimer仅可清除当前进程的定时器 server代码如下: <?php class Server { private $serv; private $timer; ...

  9. swoole 定时器 swoole_time_tick 和 swoole_time_after

    <?php class myticker{ public $server = null; CONST host = '127.0.0.1'; CONST port = 9502; public ...

随机推荐

  1. ubuntu 16.04 XDRP实现Windows远程访问

    如何通过XDRP实现Windows远程访问 下面才是本文的重点,本文主要是讲xrdp在目前最新版Ubuntu 16.04下,如果实现Windows远程访问.网上也很多相关教程,但是都需要安装xfac4 ...

  2. MSP430 CCS6.2无法启动仿真

    前几天在淘宝买了个msp430的仿真器 因为熟悉eclipse的开发环境,所以选择用ccs6.2进行开发 拿到手的时候,仿真器的固件是v2版本的 对新版本的iar和ccs都不支持 随后我使用Lite ...

  3. Docker容器的操作命令

    Docker容器的操作命令 写该文章时候的初衷是在使用Docker for windows 的时候遇到的一些问题.起初我在运行好docker客户端以后,创建了一个.NET Core应用发布到docke ...

  4. Day11 - Q - A Multiplication Game HDU - 1517

    题目链接 本题很像bash博弈,但又有些许不同,因为这里是乘法,我们可以列出前几项可能 若n=2-9,那么first可以一次取完 若n=10-18,无论first怎么取,second都能一次取完 若n ...

  5. Java自学-集合框架 ArrayList和HashSet的区别

    Java ArrayList和HashSet的区别 示例 1 : 是否有顺序 ArrayList: 有顺序 HashSet: 无顺序 HashSet的具体顺序,既不是按照插入顺序,也不是按照hashc ...

  6. 使用git commit命令时会提示"Please tell me who you are"

    在命令行中输入 git config --global user.email "邮箱地址" git config --global user.name "用户名" ...

  7. Eclipse上将maven项目部署到tomcat,本地tomcat下,webapps下,web-inf下lib下没有jar包决绝方案

    右键项目选择properties  ,选择Deployment Assembly  , 右边点击Add 然后选择  Java Build Path Entries ,,,next  ,  选择Mave ...

  8. K8s / Kubernetes 从入门到入门

    Kubernetes介绍 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器的快速轻量 - 完整的生态环境 2.什么是k ...

  9. http的3次握手与4次挥手

    Http的3次握手: 第一次握手:客户端发送一个带SYN的TCP报文到服务器,表示客户端想要和服务器端建立连接. 第二次握手:服务器端接收到客户端的请求,返回客户端报文,这个报文带有SYN和ACK确认 ...

  10. linux用户权限、系统信息相关命令(待学)

    用户权限相关命令 目标 用户 和 权限 的基本概念 用户管理 终端命令 组管理 终端命令 修改权限 终端命令 01.用户和权限的基本概念 1.1 基本概念 用户 是Linux系统工作中重要的一环, 用 ...