在Laravel中使用Process时命令执行超时

时间:2019-03-28 18:18:38

标签: node.js laravel symfony laravel-5 timeoutexception

我正在使用Laravel构建网站截图SaaS。我正在尝试从中执行命令,更确切地说是nodejs脚本;但是我不断收到ProcessTimedOutException错误。这就是魔术发生的地方,请查看take方法$process-run();行引发异常:

<?php

namespace App\Logic;

use App\Logic\TimeHelper;
use App\UrlRequest;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

class Screenshot {

    static function take(UrlRequest $urlRequest)
    {
        $name = self::generateName($urlRequest);
        $command = self::buildScreenshotCommand($name, $urlRequest);

        $startTime = TimeHelper::milliseconds();

        $process = new Process($command);
        $process->run();

        $endTime = TimeHelper::milliseconds();

        if (!$process->isSuccessful())
        {
            throw new ProcessFailedException($process);
        }

        $output = $process->getOutput();

        if (trim($output) === '')
        {
            $urlRequest->successful = 1;

            $file = self::uploadToS3($name);
            $urlRequest->image_url = $file['url'];
            $urlRequest->file_name = $name;
            $urlRequest->file_size = $file['size'];
            $urlRequest->time_it_took_to_take_screenshot_ms = $endTime - $startTime;
        }
        else
        {
            $urlRequest->error = $output;
        }

        if ($urlRequest->save())
        {
            return $urlRequest;
        }

        return false;
    }

    static function uploadToS3($name)
    {
        $name = 'screenshots/' . $name;

        Storage::disk('s3')->put($name, Storage::disk('local')->get($name), ['visibility' => 'public']); // upload to S3

        $fileSize = Storage::disk('local')->size($name);
        Storage::disk('local')->delete($name);

        return [
            'url' => Storage::disk('s3')->url($name),
            'size' => $fileSize
        ];
    }

    static function generateName($urlRequest)
    {
        $name = time() . rand(10000, 99999);
        $extension = '.png';

        if (isset($urlRequest->pdf) AND $urlRequest->pdf == 1)
        {
            $extension = '.pdf';
        }

        while (UrlRequest::where('file_name', '=', $name . $extension)->first())
        {
            $name = time() . rand(10000, 99999);
        }

        return $name . $extension;
    }

    static function buildScreenshotCommand($name, $urlRequest)
    {
        $command = 'cd ' . base_path() . ' && node puppeteer-screenshots-init.js ';
        $command .= "--url={$urlRequest->url} ";

        $fullPath = storage_path('app') . '/screenshots/' . $name;

        $command .= "--path={$fullPath} ";

        if (isset($urlRequest->pdf))
        {
            $command .= "--pdf=true ";
        }

        if (isset($urlRequest->viewport_width))
        {
            $command .= "--viewportWidth={$urlRequest->viewport_width} ";
        }

        if (isset($urlRequest->mobile))
        {
            $command .= '--mobile=true ';
        }

        if (isset($urlRequest->media_type_print))
        {
            $command .= '--mediaTypePrint=true ';
        }

        if (isset($urlRequest->user_agent))
        {
            $command .= "--userAgent={$urlRequest->user_agent}";
        }

        return $command;
    }

}

这是nodejs脚本:

require('puppeteer-screenshots').init();

puppeteer-screenshots(这是我正在尝试调用的nodejs脚本)是我为使用Google的Puppeteer软件包以简单的方式拍摄屏幕截图而编写的软件包。它是开放源代码,可在BitBucket上使用,这里是一个唯一文件的link。该程序包中似乎挂起进程的行是第138行,或者具体来说是:

await page.screenshot({path: config.path, fullPage: true});

删除此行后,过程结束,但显然不会保存屏幕截图。

此外,我尝试用exec而不是Process重写代码,但是在那种情况下,脚本只是挂起而无法完成。

此外,当从命令行执行完全相同的命令时,一切都会按预期进行。

0 个答案:

没有答案