php-如何在浏览器游戏中使事件队列在脱机模式下工作

php-如何在浏览器游戏中使事件队列在脱机模式下工作,php,events,mmo,Php,Events,Mmo,在考虑制作浏览器游戏时,我遇到了一个令人不安的麻烦。许多游戏都有一种叫做“事件队列”的东西,它的工作原理是这样的。我有一支“军队”,把它派给我的对手。我需要一些时间。当我的“军队”得到“军队”的位置时,会有一场战斗,所以我的“军队”会输赢。当我或我的对手在场时,一切都很好。某种ajax工作可以管理要调用的php脚本,并计算战斗,然后将其结果保存到数据库中。但是,如果在战斗发生时我和对手都没有登录,它怎么能工作呢?这类游戏的一个很好的例子是,当你向另一个星球发送飞船时,它可以在你注销时到达目的地,

在考虑制作浏览器游戏时,我遇到了一个令人不安的麻烦。许多游戏都有一种叫做“事件队列”的东西,它的工作原理是这样的。我有一支“军队”,把它派给我的对手。我需要一些时间。当我的“军队”得到“军队”的位置时,会有一场战斗,所以我的“军队”会输赢。当我或我的对手在场时,一切都很好。某种ajax工作可以管理要调用的php脚本,并计算战斗,然后将其结果保存到数据库中。但是,如果在战斗发生时我和对手都没有登录,它怎么能工作呢?这类游戏的一个很好的例子是,当你向另一个星球发送飞船时,它可以在你注销时到达目的地,执行战斗,获取敌人的来源并返回,因此它不仅计算星球上的星际飞船,而且还计算那个特定时刻的资源量

我一直在想,我可以节省攻击者和他的对手在数据库行中的攻击时间,并在任何玩家登录游戏时计算战斗,但这种解决方案有许多缺点。例如,如果有第三个玩家在我攻击我的对手之前进行攻击,它将改变历史上的军队统计数据(因为他可以杀死他的一部分军队),我有很多后果。另外,如果没有一个玩家会在很长一段时间内注销,他们会出现在游戏中,因为他们并没有战斗,这是不真实的


你知道如何让这样的事件排队吗?我猜使用cron也不是一个好主意——它有时会被很少使用,如果有数千名玩家,数千个cron实例可能会对性能造成致命影响。任何概念都将受到欢迎-希望我对我的问题描述得足够好:)

在您的数据库中,创建一个“作业”表(您需要的任何内容,加上过期日期,即作业完成时),每次用户创建作业时(例如,将船舶从一个集群移动到另一个集群),在此表中创建一个新条目,将EXPIRE设置为船只到达目标群集中的时间

然后,每次任何人(!)加载任何站点(甚至是startpage),脚本都会检查队列中的作业,这些作业现在应该已经完成了。如果有任何作业的EXPIRE低于现在,那么它就会执行该作业(或者,对于较大的作业,它会派生一个php cli进程来执行该作业)

假设时间是2012-12-28 12:00,游戏中有两名玩家A和B,其中A对B发起攻击,需要6小时。创建的作业过期时间为2012-12-28 18:00,内容为“Fleet foobar攻击B”

案例A: 现在,A注销,直到19:00才会发生任何事情。B登录,然后在其他任何事情发生之前(这对于确保“通知”或收件箱不会出现不同步非常重要),脚本会看到作业在表中并且过期。脚本执行作业,并向B创建通知,告知他被a的庞大舰队超限。完成作业后,一切正常(除了B的情绪)

案例B:
A注销。18:30,一名匿名用户访问startpage。脚本再次查看jobtable并执行作业。B在19:00登录并查看丢失通知。工作完成。

在我的项目中,无CRON事件队列背后的想法如下:

  • 所有事件都有“结束”时间。我使用原始UNIX time()时间戳来方便比较操作


  • 当用户“点击”(打开任何游戏页面)时,队列引擎获取所有“结束”的事件它可能使用cron作业?我不这么认为-检查-有编写的“cron-less event queue”,但是源代码有很多文件,并且是用俄语描述的,我需要几天才能找到它的工作方式,然后它做的是排队事件,无论用户请求什么,它都会处理事件队列,然后。很简单。我认为这不简单。。如果没有人调用脚本或在事件发生2天后更新数据库,则在脚本或数据库中排队并不重要。我在github上找到了一个loophp库,但还没有尝试过。。。也许这就是解决办法。游戏中还有其他玩家,不是吗?任何时候有人请求某件事,都会检查事件队列中是否有要处理的事,即使该事不属于该人;它只处理队列中需要处理的事件。如果没有人请求任何东西,那么当你再次登录时,它将得到处理。这就是我一直在寻找的解决方案(与Yanick提出的相同)。谢谢你们两位和+1的解释:)不客气。祝你的项目好运。我建议您引入一个处理作业队列的外部端点(如“game cron.php”)。然后可以从web cron服务(google“web cron服务”,web上有数百个免费的服务)调用该端点。这样,用户的加载时间就不会受到影响。