使用显示连接方式获取sse流
authorcheng <chengyf@zhihuishixun.com>
Wed, 10 Sep 2025 10:22:18 +0000 (18:22 +0800)
committercheng <chengyf@zhihuishixun.com>
Wed, 10 Sep 2025 10:22:18 +0000 (18:22 +0800)
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.h
code/sdk/zhihui/leiniao/imsl_ln/ln_api_speech_chat.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_choose.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api_story_random.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api_token.c

index 8f94b4d..5e43cfc 100644 (file)
@@ -14,7 +14,7 @@
 
 static app_task_definition_t ln_send_taskcfg = {0};
 static app_task_definition_t ln_recv_taskcfg = {0};
-#define LN_HTTP_BOARD_TASK_SIZE 0x3000
+#define LN_HTTP_BOARD_TASK_SIZE 0x4000
 
 static unsigned long g_ln_send_queue = 0xFFFFFFFF;
 static unsigned long g_ln_recv_queue = 0xFFFFFFFF;
index 28ae901..14966f0 100644 (file)
@@ -46,7 +46,7 @@ typedef struct
 /* OTA 包保存目录(最终文件仍将放在 /user/ 下)*/
 #define LN_OTA_SAVE_DIR "/user"
 
-#define LN_CLIENT_PREPARE_SIZE 2*1024
+#define LN_CLIENT_PREPARE_SIZE 4*1024
 
 #define LN_HTTP_SERVICE_CMD_GET_DEVICE_TOKEN 0x1 /* 获取设备 token */
 #define LN_HTTP_SERVICE_CMD_SPEECH_CHAT_STREAM 0x2 /* 语音对话流 */
index e9c7983..2dbf6f7 100644 (file)
@@ -121,8 +121,6 @@ uint32_t ln_speech_chat_stream_http(const char *device_id,
 
     HttpClient client = (HttpClient){0};
     HttpClientData clientData = (HttpClientData){0};
-    client.isHttp = false; /* https */
-    client.remotePort = 443;
 
     /* 自定义头:仅保留自定义业务头,Content-Type 交由 postContentType 指定 */
     char header_buf[512];
@@ -141,7 +139,7 @@ uint32_t ln_speech_chat_stream_http(const char *device_id,
     printf("chatstream header_buf: %s\n", header_buf);
 
     /* 准备缓冲区(自适应) */
-    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, 64 * 1024);
+    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE);
     if (prep != HTTP_SUCCESS)
     {
         free(body);
@@ -155,89 +153,46 @@ uint32_t ln_speech_chat_stream_http(const char *device_id,
     /* SSE 场景:响应通常为 Transfer-Encoding: chunked,打开分块标志以避免长度校验问题 */
     clientData.isChunked = true;
 
-    /* 发送请求:对易抖动错误进行有限次重试 */
-    HTTPC_RESULT res = HTTP_EUNKOWN;
-    for (int attempt = 1; attempt <= 3; attempt++)
+    int ret = -1;
+    ret = HttpClientConn(&client, LN_CHAT_URL);
+    if (ret != 0)
     {
-        res = HttpClientPostRequest(&client, LN_CHAT_URL, &clientData);
-        printf("chatstream: post attempt %d result %d\n", attempt, res);
-        if (res == HTTP_SUCCESS)
-        {
-            break;
-        }
-        if (res == HTTP_ECONN || res == HTTP_ECLSD || res == HTTP_ERECV || res == HTTP_ETIMEOUT)
-        {
-            /* 连接/收发超时类错误,短暂休眠后重建会话重试 */
-            HttpClientUnprepare(&clientData);
-            HttpClientClse(&client);
-            LOS_Msleep(200);
-            client = (HttpClient){0};
-            clientData = (HttpClientData){0};
-            client.isHttp = false;
-            client.remotePort = 443;
-            HttpClientSetCustomHeader(&client, header_buf);
-            HTTPC_RESULT prep2 = ln_http_prepare_auto(&clientData, 2048, 64 * 1024);
-            if (prep2 != HTTP_SUCCESS)
-            {
-                printf("chatstream: prepare failed on retry %d, code %d\n", attempt, prep2);
-                break;
-            }
-            clientData.postBuf = body;
-            clientData.postBufLen = body_len;
-            clientData.postContentType = content_type;
-            clientData.isChunked = true;
-            continue;
-        }
-        /* 其他错误不再重试 */
-        break;
-    }
-    if (res != HTTP_SUCCESS)
-    {
-        printf("chatstream: post failed %d\n", res);
-        HttpClientUnprepare(&clientData);
-        HttpClientClse(&client);
+        printf("connection failed, ret=0x%x\n", ret);
         free(body);
-        return ERRCODE_FAIL;
+        HttpClientUnprepare(&clientData);
+        return ret;
     }
 
-    int code = HttpClientGetResponseCode(&client);
-    if (code != 200)
+    // 发送GET请求
+    ret = HttpClientSend(&client, LN_CHAT_URL, HTTP_POST, &clientData);
+    if (ret != 0)
     {
-        printf("chatstream: HTTP %d\n", code);
-        if (clientData.responseBuf && clientData.responseBufLen > 0)
-        {
-            int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
-            do_ln_http_server_recv_data(LN_HTTP_SERVICE_CMD_SSE_RECV, clientData.responseBuf, (uint32_t)real_len);
-        }
-        HttpClientUnprepare(&clientData);
-        HttpClientClse(&client);
+        printf("send request failed, ret=0x%x\n", ret);
         free(body);
-        return ERRCODE_FAIL;
+        HttpClientClse(&client);
+        HttpClientUnprepare(&clientData);
+        return ret;
     }
 
-    /* 循环接收SSE分片并转投递到接收队列 */
-    while (1)
+    do
     {
-        HTTPC_RESULT rr = HttpClientRecvResponse(&client, &clientData);
-        if (rr == HTTP_SUCCESS || rr == HTTP_EAGAIN)
+        HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &clientData);
+        printf("chatstream: recv response result: %d\n", recv_res);
+        if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
         {
-            if (clientData.responseBuf && clientData.responseBufLen > 0)
+            // 处理接收到的数据块
+            if (clientData.contentBlockLen > 0)
             {
-                do_ln_http_server_recv_data(LN_HTTP_SERVICE_CMD_SSE_RECV, clientData.responseBuf, (uint32_t)clientData.responseBufLen);
-                HttpClientReset(&clientData);
+                do_ln_http_server_recv_data(LN_HTTP_SERVICE_CMD_SSE_RECV,
+                                            clientData.responseBuf, clientData.contentBlockLen);
             }
-            else
-            {
-                LOS_Msleep(20);
-            }
-            continue;
         }
         else
         {
-            printf("SSE recv end: %d\n", rr);
+            printf("chatstream: SSE receive ended (code: %d)\n", recv_res);
             break;
         }
-    }
+    } while (clientData.isMore);
 
     HttpClientUnprepare(&clientData);
     HttpClientClse(&client);
index 8dbcdb3..056d414 100644 (file)
@@ -124,8 +124,6 @@ uint32_t ln_story_choose_http(const char *device_id,
 
     HttpClient client = {0};
     HttpClientData clientData = {0};
-    client.isHttp = false; // 使用 HTTPS
-    client.remotePort = 443;
 
     /* 设置请求头:精简头部,避免重复(Host/Connection 交由库设置) */
     char header_buf[1024];
@@ -145,7 +143,7 @@ uint32_t ln_story_choose_http(const char *device_id,
     printf("story choose header_buf: %s\n", header_buf);
 
     /* 自适应准备 HTTP 缓冲区 */
-    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, 8 * 1024);
+    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE);
     if (prep != HTTP_SUCCESS)
     {
         printf("story choose: prepare HTTP buffer failed (code: %d)\n", prep);
@@ -159,104 +157,46 @@ uint32_t ln_story_choose_http(const char *device_id,
     clientData.postContentType = content_type;
     clientData.isChunked = true;
 
-    /* 发送请求:对易抖动错误进行有限次重试 */
-    HTTPC_RESULT res = HTTP_EUNKOWN;
-    for (int attempt = 1; attempt <= 3; attempt++)
+    int ret = -1;
+    ret = HttpClientConn(&client, LN_STORY_CHOOSE_URL);
+    if (ret != 0)
     {
-        res = HttpClientPostRequest(&client, LN_STORY_CHOOSE_URL, &clientData);
-        printf("story choose: post attempt %d result %d\n", attempt, res);
-        if (res == HTTP_SUCCESS)
-        {
-            break;
-        }
-        if (res == HTTP_ECONN || res == HTTP_ECLSD || res == HTTP_ERECV || res == HTTP_ETIMEOUT)
-        {
-            HttpClientUnprepare(&clientData);
-            HttpClientClse(&client);
-            LOS_Msleep(200);
-            client = (HttpClient){0};
-            clientData = (HttpClientData){0};
-            client.isHttp = false;
-            client.remotePort = 443;
-            HttpClientSetCustomHeader(&client, header_buf);
-            HTTPC_RESULT prep2 = ln_http_prepare_auto(&clientData, 2048, 64 * 1024);
-            if (prep2 != HTTP_SUCCESS)
-            {
-                printf("story choose: prepare failed on retry %d, code %d\n", attempt, prep2);
-                break;
-            }
-            clientData.postBuf = body;
-            clientData.postBufLen = body_len;
-            clientData.postContentType = content_type;
-            clientData.isChunked = true;
-            continue;
-        }
-        break;
-    }
-    printf("story choose: send POST request result: %d\n", res);
-    if (res != HTTP_SUCCESS)
-    {
-        printf("story choose: send POST request failed (code: %d)\n", res);
+        printf("connection failed, ret=0x%x\n", ret);
         free(body);
         HttpClientUnprepare(&clientData);
-        HttpClientClse(&client);
-        return ERRCODE_FAIL;
+        return ret;
     }
 
-    /* 检查 HTTP 响应码 */
-    int http_code = HttpClientGetResponseCode(&client);
-    printf("story choose: send POST request result: %d\n", res);
-    if (http_code != 200)
+    // 发送GET请求
+    ret = HttpClientSend(&client, LN_STORY_CHOOSE_URL, HTTP_POST, &clientData);
+    if (ret != 0)
     {
-        printf("story choose: invalid HTTP response code (%d)\n", http_code);
-        if (clientData.responseBuf && clientData.responseBufLen > 0)
-        {
-            int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
-            do_ln_http_server_recv_data(LN_HTTP_RECV_STORY_CHOOSE, clientData.responseBuf, real_len);
-        }
+        printf("send request failed, ret=0x%x\n", ret);
         free(body);
-        HttpClientUnprepare(&clientData);
         HttpClientClse(&client);
-        return ERRCODE_FAIL;
-    }
-
-    printf("story choose: send POST request success\n");
-    if (clientData.responseBuf && clientData.responseBufLen > 0)
-    {
-        int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
-        do_ln_http_server_recv_data(LN_HTTP_RECV_STORY_CHOOSE, clientData.responseBuf, real_len);
+        HttpClientUnprepare(&clientData);
+        return ret;
     }
 
-    /* 循环接收 SSE 分块数据(带累积处理)*/
-    int loop_guard = 0;
-    char sse_acc[4096] = {0};
-    int sse_acc_len = 0;
-    const int MAX_LOOP = 2000;
-    while (loop_guard++ < MAX_LOOP)
+    do
     {
         HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &clientData);
+        printf("story choose: recv response result: %d\n", recv_res);
         if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
         {
-            if (clientData.responseBuf && clientData.responseBufLen > 0)
+            // 处理接收到的数据块
+            if (clientData.contentBlockLen > 0)
             {
-                ln_sse_accumulate_and_dispatch(LN_HTTP_RECV_STORY_CHOOSE,
-                                               clientData.responseBuf,
-                                               clientData.responseBufLen,
-                                               sse_acc, &sse_acc_len, sizeof(sse_acc));
-                HttpClientReset(&clientData);
+                do_ln_http_server_recv_data(LN_HTTP_RECV_STORY_CHOOSE,
+                                            clientData.responseBuf, clientData.contentBlockLen);
             }
-            else
-            {
-                LOS_Msleep(20);
-            }
-            continue;
         }
         else
         {
             printf("story choose: SSE receive ended (code: %d)\n", recv_res);
             break;
         }
-    }
+    } while (clientData.isMore);
 
     free(body);
     HttpClientUnprepare(&clientData);
index ebf74cc..639f1b9 100644 (file)
@@ -40,7 +40,7 @@ uint32_t ln_story_random_http(const char *device_id,
     HttpClientSetCustomHeader(&client, header_buf);
 
     /* 自适应准备 HTTP 缓冲区 */
-    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, 8 * 1024);
+    HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE);
     if (prep != HTTP_SUCCESS)
     {
         printf("story random: prepare HTTP buffer failed (code: %d)\n", prep);
@@ -92,78 +92,44 @@ uint32_t ln_story_random_http(const char *device_id,
     clientData.postBufLen = json_len;
     clientData.postContentType = (char *)"application/json";
 
-    /* 发送 POST 请求 */
-    HTTPC_RESULT res = HttpClientPostRequest(&client, LN_STORY_RANDOM_URL, &clientData);
-    printf("story random: send POST request result: %d\n", res);
-    if (res != HTTP_SUCCESS)
+    int ret = -1;
+    ret = HttpClientConn(&client, LN_STORY_RANDOM_URL);
+    if (ret != 0)
     {
-        printf("story random: send POST request failed (code: %d)\n", res);
+        printf("[OTA] connection failed, ret=0x%x\n", ret);
         HttpClientUnprepare(&clientData);
-        HttpClientClse(&client);
-        return ERRCODE_FAIL;
+        return ret;
     }
 
-    printf("story random: send POST request success\n");
-
-    /* 检查 HTTP 响应码 */
-    int http_code = HttpClientGetResponseCode(&client);
-    if (http_code != 200)
+    // 发送GET请求
+    ret = HttpClientSend(&client, LN_STORY_RANDOM_URL, HTTP_POST, &clientData); 
+    if (ret != 0)
     {
-        printf("story random: invalid HTTP response code (%d)\n", http_code);
-        if (clientData.responseBuf && clientData.responseBufLen > 0)
-        {
-            char *resp = (char *)malloc(clientData.responseBufLen + 1);
-            if (resp)
-            {
-                memcpy(resp, clientData.responseBuf, clientData.responseBufLen);
-                resp[clientData.responseBufLen] = '\0';
-                printf("story random: server response: %s\n", resp);
-                free(resp);
-            }
-        }
-        HttpClientUnprepare(&clientData);
+        printf("[OTA] send request failed, ret=0x%x\n", ret);
         HttpClientClse(&client);
-        return ERRCODE_FAIL;
-    }
-
-    printf("story random: HTTP response code (%d)\n", http_code);
-    if (clientData.responseBuf && clientData.responseBufLen > 0)
-    {
-        int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
-        do_ln_http_server_recv_data(LN_HTTP_RECV_STORY_RANDOM, clientData.responseBuf, real_len);
+        HttpClientUnprepare(&clientData);
+        return ret;
     }
 
-    /* 循环接收 SSE 分块数据(带累积处理)*/
-    int loop_guard = 0;
-    char sse_acc[4096] = {0};
-    int sse_acc_len = 0;
-    const int MAX_LOOP = 2000;
-    while (loop_guard++ < MAX_LOOP)
+    do
     {
         HTTPC_RESULT recv_res = HttpClientRecvResponse(&client, &clientData);
         printf("story random: recv response result: %d\n", recv_res);
         if (recv_res == HTTP_SUCCESS || recv_res == HTTP_EAGAIN)
         {
-            if (clientData.responseBuf && clientData.responseBufLen > 0)
+            // 处理接收到的数据块
+            if (clientData.contentBlockLen > 0)
             {
-                ln_sse_accumulate_and_dispatch(LN_HTTP_RECV_STORY_RANDOM,
-                                               clientData.responseBuf,
-                                               clientData.responseBufLen,
-                                               sse_acc, &sse_acc_len, sizeof(sse_acc));
-                HttpClientReset(&clientData);
+                do_ln_http_server_recv_data(LN_HTTP_RECV_STORY_RANDOM,
+                                            clientData.responseBuf, clientData.contentBlockLen);
             }
-            else
-            {
-                LOS_Msleep(20);
-            }
-            continue;
         }
         else
         {
             printf("story random: SSE receive ended (code: %d)\n", recv_res);
             break;
         }
-    }
+    } while (clientData.isMore);
 
     HttpClientUnprepare(&clientData);
     HttpClientClse(&client);
index 60259ad..c98879c 100644 (file)
@@ -121,8 +121,6 @@ uint32_t ln_get_device_token_http(const char *device_id,
     /* 5. 发起HTTPS GET */
     HttpClient client = (HttpClient){0};
     HttpClientData clientData = (HttpClientData){0};
-    client.isHttp = false; /* https */
-    client.remotePort = 443;
     HttpClientSetCustomHeader(&client, header_buf);
 
     HTTPC_RESULT prep = HttpClientPrepare(&clientData, 2048, 4096);