Запустите команду из контроллера, чтобы избежать загрузки страницы - PullRequest
0 голосов
/ 28 июня 2019

Когда я запускаю команду с контроллера Symfony, команда выполняется, но запрос GET не завершается.

Моя команда запускает скрипт node.js, который получает rtsp-кадры, транскодированные из ffmpeg, и передает их в веб-сокет.

Это сервер Debian 9, работающий с Symfony 4, PHP 7.3.5 и Apache2.

Это действие моего контроллера show, которое вызывает команду:

    /**
     * Render view to show device details.
     * @param Request $request
     * @param $deviceid
     * @return Response
     * @Route("devices/show/{deviceid}", name="device_show", methods={"GET"})
     * @IsGranted("ROLE_OPERATOR")
     */
    public function showAction(Request $request, $deviceid)
    {
    try{
        //Find device to show from system
        $deviceToShow = $this->repository->find($deviceid);

        if ($deviceToShow) {
            $this->logger->debug('Show device: . Device has been found. Delete it... Data: ' . $deviceToShow->__toString());

            //Launch video streaming commands
            $command = new VideoServerCommand($this->entityManager, $this->logger, $this->getParameter('kernel.project_dir'));
            $input = new ArrayInput(array(
                'secret' => str_replace(' ', '', $deviceToShow->getName()),
                'http_port' => 8002,
                'ws_port' => 8005
            ));
            $output = new BufferedOutput();
            $resultCode  = $command->run($input, $output);

            $content = $output->fetch();

            if ($resultCode === 0){
                $this->logger->info('Call Video Server Command: Ok. Video Server started successfully. Console output: ' . $content);
            }else{
                $this->logger->error('Call Video Server Command: Ko. Could not start video server. Console output: ' . $content);
            }

        }else{
            $message = $this->translator->trans('Device with identifier %deviceid% was not found.',
                ['%deviceid%' => $deviceid]);

            $this->addFlash('error', $message);

            $this->logger->error('Show device: Ko. Device with identifier ' . $deviceid . ' was not found.');
        }
    }catch (Exception $exception) {
        $message = $this->translator->trans('Error while executing action. Error detail: %detail%.',
            ['%detail%' => $exception->getMessage()]);

        $this->addFlash(
            'error', $message
        );

        $this->logger->critical('Show device: Ko. Exception catched. Error detail: ' . $exception->getMessage());
    }

    $host = explode(':', $request->getUri());

    return $this->render('device/show.html.twig', array(
        'baseurl' => $host[1],
        'secret' => str_replace(' ', '', $deviceToShow->getName()),
        'device' => $deviceToShow,
    ));
    }

И это мой командный код, который запускает скрипт node.js


protected function execute(InputInterface $input, OutputInterface $output)
    {
        try {
            $this->logger->info('Start web socket: Setup websocket server...');
            $this->io = new SymfonyStyle($input, $output);
            $now = new \DateTime();
            $this->io->title('Start websocket server ' . $now->format('d-m-Y G:i:s') . '...');

            //Get input parameters
            $secret = $input->getArgument('secret');
            $tcpPort = $input->getArgument('http_port');
            $wsPort = $input->getArgument('ws_port');

            $output->writeln([
                'Video Server',// A line
                '============',// Another line
                'Starting Video Reception Socket...',// Empty line
            ]);

            //Call node websocket-relay.js
            $command = 'node ' . $this->path . '/assets/js/websocket-relay.js ' . $secret . ' ' . $tcpPort . ' ' . $wsPort;
            //Only want to execute for 60 seconds
            $nodeVideoRelay = new Process(exec($command));
            $nodeVideoRelay->setTimeout(60);
            $nodeVideoRelay->setIdleTimeout(60);

            try {
                $nodeVideoRelay->run();

                $this->logger->info('Start video streaming: OK. Video streaming successfully started...');
                $this->io->success('Start video streaming: OK. Video streaming successfully started...');
                $this->io->writeln($nodeVideoRelay->getOutput());
            } catch (ProcessTimedOutException $timedOutException) {
                $nodeVideoRelay->stop(3, SIGINT);
                $this->io->success('Start video streaming: Ok. Streaming finished.');
            }
            //}
        } catch (Exception $exception) {
            $this->logger->critical('Start video streaming: Ko. Exception catched. Error detail: ' . $exception->getMessage());
            $this->io->error('Start video streaming: Ko. Exception catched. Error detail: ' . $exception->getMessage());
        }
    }

А "websocket-relay.js" - это скрипт, полученный из https://github.com/phoboslab/jsmpeg/blob/master/websocket-relay.js

В результате страница не загружается. У меня есть другая команда, которая обрабатывает поток RTSP с помощью ffmpeg и отправляет дату в веб-сокет.

На странице, которая возвращает действие моего контроллера, появляется холст, на котором будет отображаться видео.

Я хочу, чтобы страница отображалась как можно быстрее и чтобы скрипт node.js работал в фоновом режиме, не блокируя основной процесс.

Спасибо за помощь.

...