将来在准确的位置运行PHP脚本或函数

时间:2022-01-21 14:37:45

I'm currently working on a browser game with a PHP backend that needs to perform certain checks at specific, changing points in the future. Cron jobs don't really cut it for me as I need precision at the level of seconds. Here's some background information:

我目前正在开发一个带有PHP后端的浏览器游戏,需要在未来的特定变化点执行某些检查。 Cron的工作并没有真正为我减少,因为我需要在几秒钟内达到精确度。这是一些背景信息:

  • The game is multiplayer and turn-based
  • 该游戏是多人游戏和回合制

  • On creation of a game room the game creator can specify the maximum amount of time taken per action (30 seconds - 24 hours)
  • 在创建游戏室时,游戏创建者可以指定每个动作所花费的最长时间(30秒--24小时)

Once a player performs an action, they should only have the specified amount of time to perform the next, or the turn goes to the player next in line.

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

For obvious reasons I can't just keep track of time through Javascript, as this would be far too easy to manipulate. I also can't schedule a cron job every minute as it may be up to 30 seconds late.

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

What would be the most efficient way to tackle this problem? I can't imagine querying a database every second would be very server-friendly, but it is the direction I am currently leaning towards[1].

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

Any help or feedback would be much appreciated!

任何帮助或反馈将不胜感激!

[1]:

  • A user makes a move
  • 用户采取行动

  • A PHP function is called that sets 'switchTurnTime' in the MySQL table's game row to 'TIMESTAMP'
  • 调用一个PHP函数,将MySQL表游戏行中的'switchTurnTime'设置为'TIMESTAMP'

  • A PHP script that is always running in the background queries the table for any games where the 'switchTurnTime' has passed, switches the turn and resets the time.
  • 始终在后台运行的PHP脚本会查询表中任何已经通过'switchTurnTime'的游戏,切换转弯并重置时间。

2 个解决方案

#1


0  

You can always use a queue or daemon. This only works if you have shell access to the server.

您始终可以使用队列或守护程序。这仅在您具有服务器的shell访问权限时才有效。

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

Every time you need an action to occur at a specific time, add it to a queue with a delay. I've used beanstalkd with varying levels of success.

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

You have lots of options this way. Here's two examples with 6 second intervals:

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

  • Use a cron job every minute to add 10 jobs, each with a delay of 6 seconds
  • 每分钟使用一个cron作业添加10个作业,每个作业延迟6秒

  • Write a simple PHP script that runs in the background (daemon) to adds an a new job to the queue every 6 seconds
  • 编写一个在后台(守护程序)中运行的简单PHP脚本,每隔6秒向队列添加一个新作业

#2


0  

I'm going with the following approach for now, since it seems to be the easiest to implement and test, as well as deploy on different kinds of servers/ hosting, while still acting reliably.

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

  • Set up a cron job to run a PHP script every minute.
  • 设置一个cron作业,每分钟运行一个PHP脚本。

  • Within that script, first do a query to find candidates that will have their endtime within this minute.
  • 在该脚本中,首先进行查询以查找将在此分钟内具有其结束时间的候选者。

  • Start a while-loop, that runs until 59 seconds have passed.
  • 启动一个while循环,运行直到59秒。

  • Inside this loop, check the remianing time for each candidate.
  • 在此循环内,检查每个候选人的重新安排时间。

  • If teh time limit has passed, do another query on that specific candidate to ensure the endtime hasn't changed.
  • 如果已超过时间限制,请对该特定候选项执行另一个查询以确保结束时间未发生更改。

  • If it has, re-add it to the candidates queue as nescessary. If not, act accordingly (in my case: switch the turn to the next player).
  • 如果有,请将其重新添加到候选队列中作为必要。如果没有,请采取相应行动(在我的情况下:将转弯转到下一位玩家)。

Hope this will help somebody in the future, cheers!

希望这将有助于将来的人,欢呼!

#1


0  

You can always use a queue or daemon. This only works if you have shell access to the server.

您始终可以使用队列或守护程序。这仅在您具有服务器的shell访问权限时才有效。

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

Every time you need an action to occur at a specific time, add it to a queue with a delay. I've used beanstalkd with varying levels of success.

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

You have lots of options this way. Here's two examples with 6 second intervals:

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

  • Use a cron job every minute to add 10 jobs, each with a delay of 6 seconds
  • 每分钟使用一个cron作业添加10个作业,每个作业延迟6秒

  • Write a simple PHP script that runs in the background (daemon) to adds an a new job to the queue every 6 seconds
  • 编写一个在后台(守护程序)中运行的简单PHP脚本,每隔6秒向队列添加一个新作业

#2


0  

I'm going with the following approach for now, since it seems to be the easiest to implement and test, as well as deploy on different kinds of servers/ hosting, while still acting reliably.

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

  • Set up a cron job to run a PHP script every minute.
  • 设置一个cron作业,每分钟运行一个PHP脚本。

  • Within that script, first do a query to find candidates that will have their endtime within this minute.
  • 在该脚本中,首先进行查询以查找将在此分钟内具有其结束时间的候选者。

  • Start a while-loop, that runs until 59 seconds have passed.
  • 启动一个while循环,运行直到59秒。

  • Inside this loop, check the remianing time for each candidate.
  • 在此循环内,检查每个候选人的重新安排时间。

  • If teh time limit has passed, do another query on that specific candidate to ensure the endtime hasn't changed.
  • 如果已超过时间限制,请对该特定候选项执行另一个查询以确保结束时间未发生更改。

  • If it has, re-add it to the candidates queue as nescessary. If not, act accordingly (in my case: switch the turn to the next player).
  • 如果有,请将其重新添加到候选队列中作为必要。如果没有,请采取相应行动(在我的情况下:将转弯转到下一位玩家)。

Hope this will help somebody in the future, cheers!

希望这将有助于将来的人,欢呼!