我正在为Android编写一款社交云游戏,服务器端使用PHP。游戏的几乎所有方面都是由用户或用户设备驱动的,所以大多数时候设备会向服务器发送请求,而服务器则会向设备发送响应。有时服务器也会向设备发送推送消息,但通常是响应一个用户的设备与服务器的联系。
但是有一种特殊情况,用户可以设置一个"计时器",并且在给定的时间过去之后,服务器需要将推送消息发送到所有设备。这样做的一种方法是将计时器保持在用户设备的本地,一旦计时器关闭,将信号发送到服务器以发送推送消息。然而,有几个原因,我不想这样做。例如,如果用户决定不再玩游戏或输掉游戏,计时器应该在技术上继续运行。
我在PHP中寻找了一个方法,允许我做这样的事情,但我想到的都是警报,这是不是我需要的。我也想到了cron作业,事实上,在这个论坛和其他论坛上,它们已经被推荐用于类似的情况,但由于这不是一个反复发生的事件,而是一个在任意时间点发生的一次性事件,我也不知道cron作业是我想要的。我目前最好的解决方案涉及一个cron作业,它每秒运行一次,检查这些事件中的一个是否在下一秒发生,如果发生,则发送推送消息。这是处理这种情况的正确方法吗,还是有更好的工具,只是我还没有找到?
cron非常适合定期运行的脚本,但是如果您希望在特定时间运行一次性(或两次)脚本,则可以使用Unix的'at'命令,您可以直接从PHP中使用以下代码:
/****
* Schedule a command using the AT command
*
* To do this you need to ensure that the www-data user is allowed to
* use the 'at' command - check this in /etc/at.deny
*
*
* EXAMPLE USAGE ::
*
* scriptat( '/usr/bin/command-to-execute', 'time-to-run');
* The time-to-run shoud be in this format: strftime("%Y%m%d%H%M", $unixtime)
*
**/
function scriptat( $cmd = null, $time = null ) {
// Both parameters are required
if (!$cmd) {
error_log("******* ScriptAt: cmd not specified");
return false;
}
if (!$time) {
error_log("******* ScriptAt: time not specified");
return false;
}
// We need to locate php (executable)
if (!file_exists("/usr/bin/php")) {
error_log("~ ScriptAt: Could not locate /usr/bin/php");
return false;
}
$fullcmd = "/usr/bin/php -f $cmd";
$r = popen("/usr/bin/at $time", "w");
if (!$r) {
error_log("~ ScriptAt: unable to open pipe for AT command");
return false;
}
fwrite($r, $fullcmd);
pclose($r);
error_log("~ ScriptAt: cmd=${cmd} time=${time}");
return true;
}
解决方案1:您的PHP文件可以包含一个最终循环
$con = true;
while($con)
{
//do sample operation
if($end)
$con = false;
else
sleep(5); // 5 seconds for example
}
方案2:使用cron job——根据您的CP,您可以按照指示并在特定时间调用php程序
限制:在cron作业中,两次调用之间的最小时间为1分钟
方案3:使用shell脚本并在需要时调用PHP程序
你可以让PHP休眠一段时间——之后它会恢复代码,但这是非常不推荐的,因为当一个脚本休眠时,它仍然会消耗处理器资源,如果你有多个脚本长时间休眠,它会给你的服务器带来不可能的负载。
我所知道的唯一其他选项是Cron。正如@Pete所说,你可以在PHP中管理Cron作业,例如:
http://net.tutsplus.com/tutorials/php/managing-cron-jobs-with-php-2/
这将涉及相当多的编码,但我认为这是你最好的选择。
另一个选择是让用户的浏览器使用Ajax请求和JavaScript的setTimeout
调用PHP函数,正如这个问题中公认的答案所建议的那样:
如何在页面加载10秒后在PHP中调用函数(不使用HTML)