我正在为 Laravel 5 构建一个 WebSocket 服务器包(围绕 Ratchet 进行包装,对于我的 listen 命令,我想提供将其作为后台守护进程运行的选项,以便 Ratchet 循环在运行时保持运行用户仍然可以输入新命令(与 L5 为 queue:work 命令提供此选项的方式相同),但是,我不知道如何执行此操作,谷歌搜索对我没有任何帮助。
非常感谢任何建议!
最佳答案
简单的答案:不要让您的脚本终止。
这比听起来要难一些,有几种方法可以做到这一点。一些脚本会立即fork进入多个流程,其中“主要”流程充当从子流程(实际执行工作)到终端(用于输出)的信息渡轮。这种方法的缺点是增加了进程间通信所需的复杂性(设置信号处理程序等)。
我所知道的所有解决方案或多或少都归结为一个连续的循环结构:
while(true)
{
doWork();
sleep(1);
}
这是一个守护进程。一旦开始,它就永远活着。每秒它会醒来并做工作
。缺点是,一旦启动,停止它的唯一方法是退出它 (Ctrl-C),或者,如果启动并从终端释放 ($ php myscript.php &
) 到使用非常丑陋的锤子并通过进程 ID kill
它。您可以通过注册信号处理程序并让其他 artisan 命令向该进程发送信号以终止该进程来解决此问题,并为您提供一种“干净”的方式来关闭您的进程。
另一个潜在问题是,如果您的 doWork
方法运行时间超过一秒,您将不再让循环(或多或少)每秒执行一次。如果需要任何类型的同步性,这可能会成为一个问题。
在 Laravel 的上下文中,在命令的 fire
方法内部,您只需要在其中添加一些东西(例如无限的 while
循环)来防止命令返回。
不过,我对您的建议是不要重新发明轮子。用于 PHP 的 WebSockets has been solved .
更新
如果您正在围绕 Ratchet 构建包装器,那么 Ratchet 已经解决了守护进程问题。您只需要设置服务器对象并告诉它 run()
,这就是导致阻塞执行的原因。从类似的 artisan 命令中获取此示例:
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
// Setup the Ratchet Server.
$server = IoServer::factory(
new HttpServer(
new WsServer(
$messenger
)
),
$port
);
$server->run();
// You won't reach this line unless the server crashes
构建我保存在服务提供商中的服务器的第一位,第二位实际上是在 artisan 命令中。 $messenger
变量是我对 Ratchet\MessageComponentInterface
的实现。
我的观点是,您不需要守护进程即可为 Ratchet 编写包装器。 Ratchet 已经给了你一个。
关于php - 如何让 Laravel 5 命令像恶魔一样运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29474309/