问题描述
尝试在我的电报机器人中创建掷骰子功能。 现在的工作原理:
- 当用户使用 sendDice 方法发送“roll”机器人回复并发送另一条消息时,结果为“你掷了 5,你赢了,等等等等。” > how it looks <
问题是——第二条消息不应立即出现,最好是在掷骰子动画完成后。
我的第一个也是明显的尝试是在发送第二条消息之前添加 "sleep(3)"
,它工作正常,直到我意识到它完全延迟了我的脚本执行那 3 秒。 (如果两个用户同时滚动,其中一个用户必须等到另一个人的滚动完成)。所以不酷
我可以使用什么? :c
解决方法
来自Wikipedia:
在计算中,[..] fork 是一种操作,通过它一个进程创建一个 自己的副本。
当您的 PHP 脚本运行时,您可以创建多个相互交互的进程。这些进程并发和异步运行。这样你就可以让一个进程等待发送消息,而脚本的其余部分继续运行。
除了启动另一个进程,您还可以启动另一个线程。此处解释了两者之间的技术差异: Forking vs Threading
PHP 为分叉和线程提供 Process Control Extensions。您可能需要查看 pcntl_fork() 的 PHP 文档中的示例。
根据您的需要,您可能希望使用一个框架来处理整个应用程序的并发性。如果是这种情况,我会推荐 amphp。
,最简单的选择是将“任务”添加到“队列”中。队列可以是数据库中的一个表,带有时间戳和聊天 id,何时以及向谁发送消息。启动另一个进程,例如,由cron启动,它工作一分钟。在那一分钟里,他去数据库检查是否有需要现在发送的东西。
Crontab 配置
打开 crontab
sudo crontab -e
添加下一个字符串
* * * * * php /path/to/cron.php >> /path/to/log/file/for/debug.log 2>&1
Cron 每 1 分钟运行一次您的脚本。
Cron.php "live" 60 秒 cron.php:
$now = time();
$expectedTime = $now + 60;
while (true) {
Worker::run();
if ($expectedTime < time()) {
die(0);
}
}
Where Worker::run() 你的方法,它从数据库中获取记录,检查时间戳并发送消息