Veces vista: 9
La codificación del la parte del SERVER, limitaba la concurrencia del proceso de conversión a 1 único caso, dejando en cola el resto de peticiones hasta completarse la que se estaba produciendo.
He hecho esta modificación para que se defina el número de procesos concurrentes de conversión (dependiendo del hardware, ya que es un proceso muy pesado). En el código que adjunto está a 5, pero es fácilmente ajustable, línea 106.
index.php
<?php /** * * @About: API Interface * @File: index.php * @Date: $Date:$ Agosot0 -2022 * @Version: $Rev:$ 1.0 * @Developer: Federico Guzman || Modificado por Fernando Humanes para PHP 8.1 **/ /* Los headers permiten acceso desde otro dominio (CORS) a nuestro REST API o desde un cliente remoto via HTTP * Removiendo las lineas header() limitamos el acceso a nuestro RESTfull API a el mismo dominio * Nótese los métodos permitidos en Access-Control-Allow-Methods. Esto nos permite limitar los métodos de consulta a nuestro RESTfull API * Mas información: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS **/ header("Access-Control-Allow-Origin: *"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS'); header("Access-Control-Allow-Headers: X-Requested-With"); header('Content-Type: text/html; charset=utf-8'); header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"'); include_once '../include/Config.php'; require_once("../../include/dbcommon.php"); // DataBase PHPRunner $debugCode = true; // for Debug custom_error(1,"Se inicia el Proceso de Conversión"); // To debug $post = $_POST; unset($post['file']); // Quitamos este dato porque es muy grande custom_error(2,"Variable $_POST: ".json_encode($post)); // To debug // use App\Models\Db; // Utilizamos la conexión de PHPRunner use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Selective\BasePath\BasePathMiddleware; use Slim\Factory\AppFactory; require_once __DIR__ . '/../include/slim_4.11.0/autoload.php'; $app = AppFactory::create(); $app->addRoutingMiddleware(); // $app->add(new BasePathMiddleware($app)); // No usar si se ejecuta en subdirectorio $app->addErrorMiddleware(true, true, true); $app->addBodyParsingMiddleware(); $app->setBasePath(SCRIPTS_DIR); // -------------------------------------------------------------------------------------- /* Usando POST para convertir fichero */ $app->post('/document', function(Request $request, Response $response) { $startConvert = date("Y-m-d H:i:s");; // marcar fecha de inicio // Verify Token Security $verify = authenticate($request, $response); if (is_array($verify)) { // Si es una array, es que hay error $response->getBody()->write(json_encode($verify)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } // check for required params $verify = verifyRequiredParams(array('name', 'file','option'), $request, $response); if (is_array($verify)) { // Si es una array, es que hay error $response->getBody()->write(json_encode($verify)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } $data = $request->getParsedBody(); $BlobInput=base64_decode($data['file']); // Convert Base64 $part_file = explode(".", $data['name']); // name file $ExtensionFile = $part_file[(count($part_file)-1)]; // Tipo file $new_file = substr($data['name'],0,(strlen($data['name'])-strlen($ExtensionFile)-1)).".pdf"; $option = $data['option']; // Option convert Opffice_to_PDF // -------------------- for create temporaly file -------------------------- $temp_file = tempnam(sys_get_temp_dir(), 'temp'); $part_path = pathinfo($temp_file); $temp_file1 = $part_path['dirname'].'/'.$part_path['filename'].'.'.$ExtensionFile; $phpLog = $part_path['dirname'].'/phplog.txt'; // Trace of Debug code $fp = fopen($temp_file1, 'w'); $fwrite = fwrite($fp, $BlobInput); fclose($fp); $sizeFile = filesize($temp_file1); $temp_file2 = $part_path['dirname'].'/'.$part_path['filename'].'.pdf'; do { // Para dotar de mútiples bloqueos $action = false; // Indica que falta la conversión $limint_block = 5; for ($i=0;$i< $limint_block ; $i++) { // El Límite fija el número de procesos concurrentes $fileLock = $part_path['dirname'].'/lockConvert_'.$i.'.txt'; if (!file_exists($fileLock)) { // Si no existe, se crea $fpLock = fopen("$fileLock", "w"); fclose($fpLock); } custom_error(3,"Fichero de bloque: ".$fileLock); // To debug $fp = fopen($fileLock, "r+"); // Fichero de bloqueos para que sólo haya una única ejecución // do { // Bucle de conversión copn control de que sólo un proceso puede estar en ejecución if (flock($fp, LOCK_EX)) { // adquirir un bloqueo exclusivo // Convert to PDF custom_error(4,"Iniciamos conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug // $result = shell_exec("..\\Office_to_PDF\\OfficeToPDF.exe $temp_file1 $temp_file2"); $status = exec("..\\Office_to_PDF\\OfficeToPDF.exe $option $temp_file1 $temp_file2", $outputCommand, $result); if ($result <> 0) { // LOG $a = "Resultado de conversion: ".$result."\n".var_export($outputCommand, true)." \n"; file_put_contents($phpLog, $a, FILE_APPEND | LOCK_EX); } flock($fp, LOCK_UN); // libera el bloqueo custom_error(5,"Termina conversión de : ".$temp_file1." con bloqueo. ".$fileLock); // To debug $action = true; // Se ha hecho la conersión break; } // } while (true); fclose($fp); } if ($action) { break; } // Se termina. Se ha hecho conversión custom_error(6,"Espera en cola fichero: ".$temp_file1); // To debug sleep(1); } while (true); // ------------------ Operation with file result ------------------------------------------- $document = file_get_contents($temp_file2); unlink($temp_file); // delete file tmp unlink($temp_file1); // delete file tmp unlink($temp_file2); // delete file tmp $responseBody = array(); //capturamos los parametros recibidos y los almacxenamos como un nuevo array $param['name'] = $new_file; $param['file'] = base64_encode($document); // Write LOG $data = array(); $data["nameFile"] = $new_file; $data["sizeFile"] = $sizeFile; $data["startConvert"] = $startConvert; $data["endConvert"] = date("Y-m-d H:i:s"); DB::Insert("server_pdf_log", $data ); if ( is_array($param) ) { $responseBody["error"] = false; $responseBody["message"] = "Documento convertido satisfactoriamente!"; $responseBody["document"] = $param; $response->getBody()->write(json_encode($responseBody)); return $response ->withHeader('content-type', 'application/json') ->withStatus(200); } else { $responseBody["error"] = true; $responseBody["message"] = "Error al crear auto. Por favor intenta nuevamente."; $response->getBody()->write(json_encode($responseBody)); return $response ->withHeader('content-type', 'application/json') ->withStatus(400); } }); /* corremos la aplicación */ $app->run(); /*********************** USEFULL FUNCTIONS **************************************/ /** * Verificando los parametros requeridos en el metodo */ function verifyRequiredParams($required_fields, Request $request, Response $response) { $error = false; $error_fields = ""; $request_params = $request->getParsedBody(); foreach ($required_fields as $field) { if (!isset($request_params[$field]) || strlen(trim($request_params[$field])) <= 0) { $error = true; $error_fields .= $field . ', '; } } if ($error) { // Required field(s) are missing or empty // echo error json and stop the app $responseBody = array(); $responseBody["error"] = true; $responseBody["message"] = 'Required field(s) ' . substr($error_fields, 0, -2) . ' is missing or empty'; return $responseBody; } return true; } /** * Validando parametro email si necesario; un Extra ;) */ function validateEmailRest($email, Request $request, Response $response) { $responseBody = array(); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $responseBody["error"] = true; $responseBody["message"] = 'Email address is not valid'; return $responseBody; } return true; } /** * Revisa si la consulta contiene un Header "Authorization" para validar */ function authenticate(Request $request, Response $response) { // Getting request headers $headers = $request->getHeaders(); // Verifying Authorization Header if (isset($headers['Authorization'])) { // get the api key $token = $headers['Authorization']; // validating api key if (!($token[0] == API_KEY)) { //API_KEY declarada en Config.php // api key is not present in users table $responseBody["error"] = true; $responseBody["message"] = "Acceso denegado. Token inválido"; // Error 401 return $responseBody; } else { //procede utilizar el recurso o metodo del llamado return true; } } else { // api key is missing in header $responseBody["error"] = true; $responseBody["message"] = "Falta token de autorización"; // error 400 return $responseBody; } } ?>
Si te interesa este artículo, sigue leyendo accediendo a este enlace.