在将来的某个特定时间点运行PHP脚本或函数


Running a PHP script or function at an exact point in the future

我目前正在开发一款带有PHP后端的浏览器游戏,该游戏需要在未来的特定变化点执行某些检查。Cron的工作对我来说并没有真正的意义,因为我需要秒级的精度。以下是一些背景信息:

  • 游戏是多人游戏,回合制
  • 在创建游戏室时,游戏创建者可以指定每个动作所花费的最大时间(30秒-24小时)

一旦玩家执行了一个动作,他们应该只有指定的时间来执行下一个,或者轮到下一个玩家。

出于显而易见的原因,我不能仅仅通过Javascript来跟踪时间,因为这太容易操作了。我也不能每分钟安排一次cron作业,因为它可能会延迟30秒。

解决这个问题最有效的方法是什么?我无法想象每秒查询一个数据库会对服务器非常友好,但这正是我目前倾向的方向[1]。

如有任何帮助或反馈,我们将不胜感激!

[1] :

  • 用户移动
  • 调用了一个PHP函数,该函数将MySQL表的游戏行中的‘switchTurnTime’设置为"IMESTAMP"
  • 始终在后台运行的PHP脚本会在表中查询"switchTurnTime"已过的任何游戏,切换回合并重置时间

您可以始终使用队列或守护进程。只有当您具有对服务器的shell访问权限时,这才有效。

https://stackoverflow.com/a/858924/890975

每次需要在特定时间执行某个操作时,都要将其添加到具有延迟的队列中。我使用beanstalkd取得了不同程度的成功。

这样你有很多选择。这里有两个6秒间隔的例子:

  • 每分钟使用一个cron作业添加10个作业,每个作业延迟6秒
  • 编写一个在后台运行的简单PHP脚本(守护进程),每隔6秒向队列添加一个新作业

我现在采用以下方法,因为它似乎是最容易实现和测试的方法,也可以部署在不同类型的服务器/主机上,同时仍然可靠。

  • 设置一个cron作业,以便每分钟运行一个PHP脚本
  • 在该脚本中,首先执行查询以查找结束时间在该分钟内的候选者
  • 开始一个while循环,直到59秒过去
  • 在这个循环中,检查每个候选人的复习时间
  • 如果时间限制已经过去,请对该特定候选人进行另一次查询,以确保结束时间没有更改
  • 如果有,则必要时将其重新添加到候选队列中。如果没有,就采取相应的行动(在我的情况下:将回合切换到下一个玩家)

希望这对将来的人有所帮助,干杯!