如何使用定时器功能,每间隔一段时间,给用户发送消息

whhema

如何在workerman的Demo的基础上,实现 每间隔一段时间,服务器向指定的用户推送消息数据。
如何把定时代码和workerman的代码结合起来?

21059 1 0
1个回答

walkor

首先 讲解下如何在其它项目中通过workerman向客户端转发数据(只针对Gateway/Worker模型开发的应用 如applications/Demo、workerman-chat、workerman-todpole等)

以applications/Demo为例
在其它项目中(比如apache运行的web项目),只要将applications/Demo这个文件夹拷贝到你的项目下,然后include Demo/Lib/Gateway.php ,然后直接使用\Lib\Gateway::sendToClient \Lib\Gateway::sendToAll 发送向客户端数据了

如何定时
定时最简单的方法是通过 linux的cron来做,也就是定时运行一下php的脚本。缺点是corn脚本最小时间间隔为1分钟,如果时间间隔符合你的需求则可以使用cron,具体操作可以百度下

如果你需要秒级别的定时,则可以使用php脚本来做。php脚本里面一个while死循环,里面配合sleep/usleep。然后运行nohup php youcron.php & 就一直后端运行了。缺点是如果脚本写的不健壮,出现FatalError这个脚本就被终止了

也可以使用workerman来做定时,workerman中有一个设定定时任务的接口 \Man\Core\Lib\Task 可以在workerman中直接调用。

用workerman做定时任务

首先新建一个进程文件,假如有两个定时任务,一个是每2秒向所有客户端发送一段数据,另外一个是每隔10秒向所有客户端发送一段数据
新建一个文件 applications/Demo/Task.php

<?php
/*
 *  一个定时任务,向通过workerman定时向客户端发送数据
 */
// 向客户端发送数据必须载入这个类
require_once __DIR__ . '/Lib/Gateway.php';

class Task extends Man\Core\SocketWorker
{
    // 子进程启动时会运行onStart, 整个进程生命周期只运行一次,这里用来注册定时任务
    public function onStart()
    {
        // 初始化定时任务,让$this->event负责定时触发
        \Man\Core\Lib\Task::init($this->event);

        // 定时任务1的时间间隔2秒
        $time_interval1 = 2;
        // 设定定时任务
        \Man\Core\Lib\Task::add($time_interval1, function(){
            // 任务逻辑,这里只发了一个字符串
            \Lib\Gateway::sendToAll("I'm Task 1\n");
        });

        // 定时任务2的时间间隔10秒
        $time_interval2 = 10;
        // 设定定时任务,定时运行 $this->dealProcess();
        \Man\Core\Lib\Task::add($time_interval2, array($this, 'taskTwo'));
    }

    // 另外一个要定时运行的类成员函数
    public function taskTwo()
    {
       \Lib\Gateway::sendToAll("I'm Task 2\n");
    }

    // 这里不接收请求,函数留空
    public function dealInput($recv_buffer){}

    // 这里不接收请求,函数留空 
    public function dealProcess($recv_buffer){}
}

然后新建一个配置进程文件
applications/Demo/conf.d/Task.conf

;定时任务进程入口文件
worker_file = ../Task.php
;启动多少进程,定时任务一般是一个进程,也可以开多个但是要注意多进程会不会给你带来并发问题
start_workers=1
;以哪个用户运行这个worker进程,要设置成权限较低的用户,如 www-data nobody
user=root

最后启动workerman并测试
运行 ./workerman/bin/workermand restart
然后运行telnet 127.0.0.1 8480
就可以看到定时任务的效果了,类似如下

telnet 127.0.0.1 8480
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
type in your name:
ff
chat room login success, your client_id is 7, name is ff
use client_id:words send message to one user
use words send message to all
ff come
I'm Task 1
I'm Task 1
I'm Task 1
I'm Task 2
I'm Task 1
I'm Task 1
I'm Task 1
I'm Task 1
I'm Task 1
I'm Task 2
  • 暂无评论
年代过于久远,无法发表回答
🔝