Procházet zdrojové kódy

调整gpt-image2的超时时间

lh před 1 měsícem
rodič
revize
64c2a8f019

+ 66 - 50
app/Services/AIGeneration/AIImageGenerationService.php

@@ -254,76 +254,95 @@ class AIImageGenerationService
             dLog('generate')->info('开始调用GPT-Image2 API', ['task_id' => $task->task_id, 'mode' => $isEditMode ? 'edit' : 'generation']);
             logDB('generate', 'info', '开始调用GPT-Image2 API', ['task_id' => $task->task_id, 'mode' => $isEditMode ? 'edit' : 'generation']);
             
-            // 创建专用客户端,设置更长的超时时间(图片生成可能需要较长时间)
+            // 创建专用客户端,优化配置
             $gptClient = new Client([
-                'timeout' => 600, // 10分钟超时
-                'connect_timeout' => 30, // 连接超时30秒
-                'read_timeout' => 600, // 读取超时10分钟
-                'http_errors' => false, // 不自动抛出HTTP错误,手动处理
+                'timeout' => 1800, // 2分钟超时
+                'connect_timeout' => 10, // 连接超时10秒
+                'http_errors' => false, // 不自动抛出HTTP错误
+                'verify' => false, // 禁用SSL验证(如果有证书问题)
+                'allow_redirects' => true,
             ]);
             
             // 根据是否有参考图选择不同的请求方式
             if ($isEditMode) {
-                // 使用 multipart/form-data 格式
+                // 使用原生 cURL 处理 multipart/form-data 格式
                 $imageUrl = is_array($task->ref_img_url) ? $task->ref_img_url[0] : $task->ref_img_url;
                 
                 dLog('generate')->info('下载参考图片', ['image_url' => $imageUrl]);
                 
-                // 下载图片到临时文件
+                // 下载图片内容
                 $imageContent = @file_get_contents($imageUrl);
                 if ($imageContent === false) {
                     throw new \Exception('下载参考图片失败: ' . $imageUrl);
                 }
                 
-                $tempFile = tempnam(sys_get_temp_dir(), 'gpt_image_');
+                dLog('generate')->info('参考图片下载完成', ['size' => strlen($imageContent)]);
+                
+                // 保存为临时文件(cURL 需要真实文件路径)
+                $extension = pathinfo(parse_url($imageUrl, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'png';
+                $tempFile = tempnam(sys_get_temp_dir(), 'gpt_img_') . '.' . $extension;
                 file_put_contents($tempFile, $imageContent);
                 
-                dLog('generate')->info('参考图片已保存到临时文件', ['temp_file' => $tempFile, 'size' => filesize($tempFile)]);
+                dLog('generate')->info('临时文件创建成功', ['file' => $tempFile, 'size' => filesize($tempFile)]);
                 
-                $multipart = [
-                    [
-                        'name' => 'image',
-                        'contents' => fopen($tempFile, 'r'),
-                        'filename' => basename($imageUrl),
-                    ],
-                    [
-                        'name' => 'prompt',
-                        'contents' => $task->prompt,
-                    ],
-                    [
-                        'name' => 'model',
-                        'contents' => 'gpt-image-2',
-                    ],
+                // 构建 POST 字段
+                $postFields = [
+                    'image' => new \CURLFile($tempFile, 'image/' . $extension, 'image.' . $extension),
+                    'prompt' => $task->prompt,
+                    'model' => 'gpt-image-2',
+                    'n' => (int)$task->image_num,
                 ];
                 
                 // 尺寸参数
                 if ($task->width && $task->height) {
-                    $multipart[] = [
-                        'name' => 'size',
-                        'contents' => $task->width . 'x' . $task->height,
-                    ];
+                    $postFields['size'] = $task->width . 'x' . $task->height;
                 }
                 
-                dLog('generate')->info('GPT-Image2 API参数(编辑模式)', ['api_url' => $api_url, 'prompt' => $task->prompt, 'image_url' => $imageUrl, 'size' => ($task->width . 'x' . $task->height)]);
+                dLog('generate')->info('GPT-Image2 API参数(编辑模式-cURL)', ['api_url' => $api_url, 'prompt' => $task->prompt, 'size' => ($task->width . 'x' . $task->height), 'n' => (int)$task->image_num]);
                 logDB('generate', 'info', 'GPT-Image2任务提交(编辑模式)', ['task_id' => $task->task_id, 'api_url' => $api_url, 'image_url' => $imageUrl, 'prompt' => $task->prompt]);
                 
-                dLog('generate')->info('开始发送multipart请求到GPT-Image2 API');
                 $startTime = microtime(true);
                 
-                // 调用GPT-Image2 API (multipart/form-data)
-                $response = $gptClient->post($api_url, [
-                    'headers' => [
-                        'Authorization' => 'Bearer ' . $apiKey,
-                        'Accept' => 'application/json',
+                // 使用原生 cURL
+                $ch = curl_init();
+                curl_setopt_array($ch, [
+                    CURLOPT_URL => $api_url,
+                    CURLOPT_RETURNTRANSFER => true,
+                    CURLOPT_POST => true,
+                    CURLOPT_POSTFIELDS => $postFields,
+                    CURLOPT_HTTPHEADER => [
+                        'Authorization: Bearer ' . $apiKey,
+                        'Accept: application/json',
+                        'Expect:', // 移除 Expect: 100-continue,避免等待
                     ],
-                    'multipart' => $multipart,
+                    CURLOPT_TIMEOUT => 1800, // 不设超时,等待完成
+                    CURLOPT_CONNECTTIMEOUT => 30,
+                    CURLOPT_SSL_VERIFYPEER => false,
+                    CURLOPT_SSL_VERIFYHOST => false,
+                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // 强制使用 HTTP/1.1
                 ]);
                 
-                $elapsed = round(microtime(true) - $startTime, 2);
-                dLog('generate')->info('GPT-Image2 API请求完成', ['elapsed' => $elapsed . 's', 'status_code' => $response->getStatusCode()]);
+                dLog('generate')->info('开始发送cURL请求');
+                
+                $responseBody = curl_exec($ch);
+                $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+                $curlError = curl_error($ch);
+                $curlErrno = curl_errno($ch);
+                curl_close($ch);
                 
                 // 删除临时文件
                 @unlink($tempFile);
+                
+                $elapsed = round(microtime(true) - $startTime, 2);
+                dLog('generate')->info('cURL请求完成', ['elapsed' => $elapsed . 's', 'http_code' => $statusCode, 'curl_errno' => $curlErrno]);
+                
+                if ($curlErrno !== 0) {
+                    throw new \Exception('cURL错误: ' . $curlError . ' (错误码: ' . $curlErrno . ')');
+                }
+                
+                if (empty($responseBody)) {
+                    throw new \Exception('API返回空响应,HTTP状态码: ' . $statusCode);
+                }
             } else {
                 // 使用 JSON 格式 (原有的文生图模式)
                 $apiParams = [
@@ -339,7 +358,6 @@ class AIImageGenerationService
                 dLog('generate')->info('GPT-Image2 API参数', $apiParams);
                 logDB('generate', 'info', 'GPT-Image2任务提交', ['task_id' => $task->task_id, 'api_url' => $api_url, 'params' => $apiParams]);
                 
-                dLog('generate')->info('开始发送JSON请求到GPT-Image2 API');
                 $startTime = microtime(true);
                 
                 // 调用GPT-Image2 API
@@ -351,21 +369,19 @@ class AIImageGenerationService
                     'json' => $apiParams,
                 ]);
                 
+                $statusCode = $response->getStatusCode();
+                $responseBody = $response->getBody()->getContents();
+                
                 $elapsed = round(microtime(true) - $startTime, 2);
-                dLog('generate')->info('GPT-Image2 API请求完成', ['elapsed' => $elapsed . 's', 'status_code' => $response->getStatusCode()]);
+                dLog('generate')->info('Guzzle请求完成', ['elapsed' => $elapsed . 's', 'http_code' => $statusCode]);
+                
+                if (empty($responseBody)) {
+                    throw new \Exception('API返回空响应,HTTP状态码: ' . $statusCode);
+                }
             }
             
-            // 获取响应状态码
-            $statusCode = $response->getStatusCode();
-            dLog('generate')->info('GPT-Image2 API HTTP状态码: ' . $statusCode);
-            
-            // 读取响应内容
-            $responseBody = $response->getBody()->getContents();
-            dLog('generate')->info('GPT-Image2 API响应原始数据长度: ' . strlen($responseBody));
-            
-            if (empty($responseBody)) {
-                throw new \Exception('API返回空响应,HTTP状态码: ' . $statusCode);
-            }
+            // 解析响应
+            dLog('generate')->info('响应数据长度', ['length' => strlen($responseBody)]);
             
             $responseData = json_decode($responseBody, true);