代码之家  ›  专栏  ›  技术社区  ›  DerpyNerd

在Symfony做一份无止境的工作

  •  0
  • DerpyNerd  · 技术社区  · 7 年前
    • Symfony:4.1
    • PHP:7.1

    我有正在使用的websocket服务器 Ratchet .websocket本身可以工作。我可以用Symfony的 commands

    php bin/console app:websocket:execute
    

    我很难回避这些问题:

    1. 你需要用一个终端来运行这个命令
    2. 大多数网络托管服务不允许您访问终端
    3. 我希望管理员能够打开和关闭websocket服务器
    4. 管理员不需要知道终端是什么

    对于问题1,我尝试使用这种“分离”欺骗,但它无法解决问题2:

    php bin/console app:websocket:execute > /dev/null 2>&1 &
    

    为了解决这四个问题。我试过使用一个过程。但这种方法的问题是:

    • $process->run() -使用 php bin/console 总是以超时结束
    • $process-start() -启动进程意味着它异步运行,但也意味着一旦请求结束,进程就会终止,我的websocket服务器也会终止。

    下面是一个例子

    $process = new Process("php bin/console");
    $process->setWorkingDirectory(getcwd() . "/../");
    $process->setTimeout(10);
    $process->run(); // Stalls for 10 seconds, then throws timeout exception
    $process-start(); // Doesn't stall, but terminates at end of request
    
    // $process->run() ==== unreachable code
    if (!$process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }
    

    我尝试创建一个控制台应用程序,并从那里运行命令。但同样的问题也适用于这里。

    $application = new Application($this->kernel);
    $application->setAutoExit(false);
    
    $input = new ArrayInput(array(
        'command' => 'app:websocket:execute'
    ));
    
    try {
        $ob = new BufferedOutput();
        $application->run($input, $ob);
        $output = $ob->fetch();
    } catch (\Exception $e) {
        return null;
    }
    

    最后,我尝试了一个叫做 DtcQueueBundle ,因为它提到了以下内容:

    易用性

    • 用一两行代码开始后台任务
    • 轻松添加后台工作人员服务
    • 用几行代码将任何代码转换为后台任务

    所以我按照他们的要求,创建了一个worker,并尝试将其作为“后台任务”运行

    use App\Ratchet\ForumUpdater;
    use Ratchet\Http\HttpServer;
    use Ratchet\Server\IoServer;
    use Ratchet\WebSocket\WsServer;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class SocketWorker extends \Dtc\QueueBundle\Model\Worker
    {
        public function execute()
        {
            $server = IoServer::factory(
                new HttpServer(
                    new WsServer(
                        new ForumUpdater()
                    )
                ),
                8080
            );
    
            $server->run();
    
            return "Websocket started";
        }
    
        public function getName()
        {
            return "websocket-server";
        }
    }
    

    他们的医生绝对是最差的!我甚至试图挖掘他们的代码,从我的控制器内部开始工作。但我无法让它以超然的方式运行。

    不管发生什么,我相信我的命令没有运行,因为它会提升我的PHP线程。我想知道,有没有可能将这个无休止的过程分离开来?甚至可以同时运行两个PHP实例吗?我想是的!

    谢谢你的帮助,抱歉发了这么长的帖子

    0 回复  |  直到 7 年前