php 浏览器请求服务端,服务端用exec去触发php脚步程序执行。当脚本程序被执行时,出现了阻塞情况

新手上路,请多包涵

描述

php 浏览器请求服务端,服务端用shell_exec去触发php脚步程序执行。当脚本程序被执行时,出现了阻塞情况,客户端的请求必须等到脚本程序里面退出。

脚本程序大致内容

脚本程序大致是使用php stream系列函数去连接某个tcp协议的服务端,收到服务端相应的数据就退出。

客户端相关相关代码

        if (Yii::$app->request->isAjax) {
            Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
            $model = $this->findModel($id);
            if (!empty($model->pdf_path)) {
                return ['statusCode' => 300, 'message' => '该文件已被转换过pdf!']; 
            }

            $model->sendPreview();

            return ['statusCode' => 200, 'message' => '请求发送成功!'];  
        }
    //sendPreview代码
        $retArr = [];
        $retVal = '';
        exec('php ' . Yii::$app->basePath . '/../yii init/office-to-pdf ' . $this->id, $retArr, $retVal);

脚本程序相关代码

// 建立socket连接
$client = stream_socket_client($address, $errno, $errmsg, $config['stream_timeout']);
if (!$client) {
    exit("$errmsg\n");
}

// 设置成阻塞
stream_set_blocking($client, $config['blocking_mode']);
    while (true) {
        $res1 = explode("\n", fread($client, 216));
        $res = json_decode($res1[0], true);
        $current_ftell = null;
        if ($res) {
            if ( $config['transfer_state'][4] === $res['code']) {
                echo 'The file upload failed ';
                if (isset($res['msg'])) echo $res['msg'];
                echo "\n";
                break;
            }
        ...
    }

模糊概念

这里是因为脚本里面的stream_set_blocking($client, $config['blocking_mode']);和while(true)导致的?
我的想法:客户端发起一个请求到nginx,nginx在和php-fpm通讯,php-fpm开启一个一个进程执行代码
     那exec触发php脚本,是在php cli处理的。这里php-fpm 和cli有关联?

求解

知识能力有限,但是求甚解,秉持“知其然,知其所以然”,请大家赐教

阅读 3k
4 个回答
  1. 你的问题和php-cli没有任何联系,不要走弯路。
  2. exec 是同步阻塞动作,如果 exec 调用的脚本卡住了,那么整个 php 就都会卡住。
  3. 你的需求应该是上传doc文件并在服务器端转换成pdf,这个动作本身就很耗时。业界都是上传后直接结束上传流程,返回用户状态后就结束。后台异步做 doc2pdf 。
新手上路,请多包涵

有人回答吗?

你提的问题有点混乱,你设置了阻塞函数,当然会阻塞。如果你用cli运行命令,那就不会走阻塞函数。但是本身PHP就是阻塞的,你执行文件转换的时候就会阻塞啊。
至于fpm和cli的关系,你可以看这个回答https://segmentfault.com/q/10...

服务器 CLI 挂队列。把任务 push 进队列,给前台一个回调地址用来查询结果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题