繁体   English   中英

每隔X秒执行一次PHP方法?

[英]execute a PHP method every X seconds?

背景:

我正在制作一个PHP websocket服务器( 这里 )作为DAEMON运行,其中显然有一个主循环监听套接字连接和传入数据,所以我不能只创建一个带sleep(x_number_of_seconds);的其他循环sleep(x_number_of_seconds); 因为它会冻结我的整个服务器。

我不能用CRON作业执行外部脚本或者也可以分叉新进程(我猜)因为我必须在我的服务器类的范围内将数据发送到连接的客户端套接字。

有谁知道在PHP中实现这个的神奇技巧? :/

一些疯狂的想法:

  1. 使用microtime(true)跟踪最后一个循环执行时间,并将其与每个循环上的当前时间进行比较,如果它是我所需的X秒间隔,则执行方法...这将导致非常醉并且不一致的间隔环。
  2. 在浏览器中运行JavaScript setInterval() ,通过websocket与我的服务器通信并告诉它执行我的方法......我说他们疯狂的想法!

关于我正在努力实现的目标的其他信息:

我正在做一个小小的在线游戏(RPG之类),我想在其中添加一些NPC,每隔X秒更新一次。

还有其他方法可以实现这一目标吗? 我错过了什么吗? 我应该在Node.js中重写我的服务器吗?

非常感谢您的帮助 !

一个完美的替代品不存在接缝,所以我将使用我疯狂的解决方案#1:

$this->last_tick_time = microtime(true);
$this->tick_interval = 1;
$this->tick_counter = 0;

while(true)
{
    //loop code here...

    $t= microtime(true) - $this->last_tick_time;

    if($t>= $this->tick_interval)
    {
        $this->on_server_tick(++$this->tick_counter);
        $this->last_tick_time = microtime(true) - ($t- $this->tick_interval);
    }
}

基本上,如果自上次服务器tick后经过的时间大于或等于我想要的滴答间隔,则执行on_server_tick()方法。 而且最重要的是:我们减去时间溢出,以使下一个滴答发生得更快,如果这个发生得太晚了。 这样我们填补了空白,最后,如果socket_select超时设置为1秒,我们将永远不会有大于1.99999999+秒的间隙。

我也跟踪tick计数器,这样我可以使用modulo(%) 在多个时间间隔上执行代码,如下所示:

protected function on_server_tick($counter)
{
    if($counter%5 == 0)
    {
        // 5 seconds interval
    }

    if($counter%10 == 0)
    {
        // 10 seconds interval
    }
}

这涵盖了我的所有需求! :d

不要担心PHP,我不会用Node.js替换你,你还是我的朋友。

在我看来,你使用的websocket-framework太原始了,不允许你的服务器在等待来自客户端的连接时做其他有用的事情。 对PHP的socket_select()函数的唯一调用被硬编码为一秒超时,并且当时间用完时它什么都不做。 它真的应该允许回调或外部循环。

请查看http://php.net/manual/en/function.socket-select.php手册页。 最后一个参数是超时时间。 socket_select()等待套接字上的传入数据或直到超时时间结束,这听起来像你想要做的,但是库没有提供它。 然后看看库如何在core / classes / SocketServer.php中使用它。

我假设你调用run()然后它永远不会返回到你的调用代码,直到它在套接字上得到一条消息,这阻止你做任何事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM