return -1;
}
+ // 检查是否是退出对话场景
+ bool is_exit_dialogue = (strcmp(reason, "退出对话") == 0);
+
// 检查是否需要在1秒内有数据时触发重连
bool need_reconnect = ln_ws_check_binary_data_interrupt();
LN_WS_DEBUG("Sending VoiceChatInterrupt: %s\n", json_string);
// 发送消息
+ int ret = uapi_ws_send_text(json_string);
+ if (ret == 0) {
+ LN_WS_DEBUG("VoiceChatInterrupt sent successfully\n");
+ }
// 清理资源
- int ret=0;
- if (need_reconnect || (g_audio_chat_ctx.finish_state == LN_CHAT_SENT_END_NO_REPLY))
- {
- ret = uapi_ws_send_text(json_string);
- if (ret == 0) {
- LN_WS_DEBUG("VoiceChatInterrupt sent successfully\n");
- }
- // 如果检测到频繁数据接收,直接重连
- LN_WS_INFO("Triggering reconnection due to frequent binary data reception\n");
- if (ln_ws_reconnect() != 0) {
- LN_WS_ERROR("Failed to reconnect after frequent data reception\n");
+ // 如果需要重连
+ if (need_reconnect || (g_audio_chat_ctx.finish_state == LN_CHAT_SENT_END_NO_REPLY)) {
+ if (is_exit_dialogue) {
+ // 只有退出对话场景,才等待资源清理完成后再重连
+ // 资源清理(AUDIO_DEINIT)通过消息队列异步执行,需要等待清理完成
+ LN_WS_INFO("Exit dialogue mode, waiting for resource cleanup before reconnection\n");
+
+ // 轮询检查资源清理完成标志,最多等待500ms
+ const uint32_t max_wait_ms = 500;
+ const uint32_t check_interval_ms = 20; // 每20ms检查一次
+ uint32_t waited_ms = 0;
+ bool cleanup_complete = false;
+
+ while (waited_ms < max_wait_ms) {
+ // 检查音频是否已反初始化(资源清理完成的标志)
+ if (!ln_ws_is_audio_initialized()) {
+ cleanup_complete = true;
+ LN_WS_INFO("Resource cleanup completed after %u ms\n", waited_ms);
+ break;
+ }
+ LOS_Msleep(check_interval_ms);
+ waited_ms += check_interval_ms;
+ }
+
+ if (!cleanup_complete) {
+ LN_WS_WARN("Resource cleanup timeout after %u ms, proceeding with reconnection anyway\n", max_wait_ms);
+ }
+
+ // 再次检查连接状态,确保在等待期间连接状态未改变
+ if (g_ws_connected == WS_STATE_CONNECTED) {
+ LN_WS_INFO("Triggering reconnection after exit dialogue (resource cleanup %s)\n",
+ cleanup_complete ? "completed" : "timeout");
+ if (ln_ws_reconnect() != 0) {
+ LN_WS_ERROR("Failed to reconnect after exit dialogue\n");
+ }
+ } else {
+ LN_WS_WARN("Connection state changed during wait, skip reconnection: %d\n", g_ws_connected);
+ }
+ } else {
+ // 非退出对话场景(如二进制数据间隔检查触发的重连),直接重连
+ // WebSocket重连是网络层操作,与音频资源无关
+ if (g_ws_connected == WS_STATE_CONNECTED) {
+ LN_WS_INFO("Triggering reconnection %s\n",
+ need_reconnect ? "due to binary data interrupt" : "due to chat finish state");
+ if (ln_ws_reconnect() != 0) {
+ LN_WS_ERROR("Failed to reconnect\n");
+ }
+ } else {
+ LN_WS_WARN("Connection state changed, skip reconnection: %d\n", g_ws_connected);
+ }
}
}
- else {
- LN_WS_INFO("no to send VoiceChatInterrupt\n");
- }
cJSON_free(json_string);
cJSON_Delete(json);
if (data_msg->command == WS_CMD_RANDOM_STORY_RESPONSE) {
cJSON *data_obj = cJSON_GetObjectItem(root, "data");
if (data_obj && cJSON_IsObject(data_obj)) {
+ // 根据协议,先检查errorCode字段(在data对象中,不在data.data中)
+ cJSON *error_code = cJSON_GetObjectItem(data_obj, "errorCode");
+ if (error_code && !cJSON_IsNull(error_code)) {
+ // 如果errorCode不为null,表示发生了错误
+ // 根据协议,错误响应中会包含data字段,其中包含错误信息和音频URL
+ LN_WS_WARN("RandomStoryResponse error: errorCode=%s\n",
+ cJSON_IsString(error_code) ? error_code->valuestring : "unknown");
+ // 错误响应中仍然会包含data字段,继续解析以便播放错误音频
+ }
+
// 解析finished字段(先解析到data_msg,但不更新全局上下文)
cJSON *finished = cJSON_GetObjectItem(data_obj, "finished");
if (finished && cJSON_IsBool(finished)) {
}
}
- // 解析data.data字段
+ // 解析data.data字段(根据协议,即使有错误,data字段也可能存在,包含错误信息和音频URL)
cJSON *data_data = cJSON_GetObjectItem(data_obj, "data");
if (data_data && cJSON_IsObject(data_data)) {
// 解析storyTheme字段,存储到text_content中