我正在为Laravel 5构建一个WebSocket Server包(Ratchet的包装器),对于我的listen命令,我想提供将其作为后台守护进程运行的选项,以便棘轮循环继续运行,而用户仍然可以输入新命令(就像L5为队列提供此选项的方式:工作命令一样),但是,我不知道如何做到这一点,谷歌搜索没有'请帮助我。
非常感谢任何建议!
答案 0 :(得分:4)
简单的答案:不要让你的脚本终止。
这比听起来更难,而且有几种方法可以做到这一点。有些脚本会立即fork进入多个进程,其中'main'用作从子进程(实际执行工作)到终端(用于输出)的信息传输。这种方法的缺点是进程间通信发生所需的复杂性增加(设置信号处理程序等)。
我所知道的所有解决方案或多或少都归结为一个连续的循环结构:
while(true)
{
doWork();
sleep(1);
}
这是守护进程。一旦开始,它总是活着的。每隔一秒它就会醒来并doWork
。缺点是,一旦启动,阻止它的唯一方法是打破它(Ctrl-C),或者,如果从终端($ php myscript.php &
)启动和释放,使用真正丑陋的锤子和{{ 1}}由进程ID。你可以通过注册信号处理程序和其他工匠命令来解决这个问题,这些命令会向这个进程发送信号以终止,并且会给你一个“干净”的方式来关闭你的进程。
另一个潜在的问题是,如果你的kill
方法需要花费的时间超过一秒钟,那么你将不再需要每秒执行一次(或多或少)循环。如果需要任何同步性,这可能是一个问题。
在Laravel的上下文中,在命令的doWork
方法内部,你只需要一些东西(例如无限fire
循环)来阻止命令返回。
<强>更新强>
如果你正在构建一个围绕Ratchet的包装器,那么Ratchet已经解决了守护进程问题。您只需设置服务器对象并将其告诉while
,这是导致阻止执行的原因。以类似的工匠命令为例:
run()
构建我保留在服务提供者中的服务器的第一位,第二位实际上是在一个工匠命令中。 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
变量是$messenger
的实现。
我的观点是,您不需要守护进程来为Ratchet编写包装器。 Ratchet已经给你一个。