From 35b53158980e5b18a9908c2150b6ca59a3ba2d55 Mon Sep 17 00:00:00 2001 From: hcj <1224667075@qq.com> Date: Fri, 19 Sep 2025 19:58:51 +0800 Subject: [PATCH] =?utf8?q?=E4=BF=AE=E6=94=B9ln=20ws=E5=87=BD=E6=95=B0?= =?utf8?q?=E8=B0=83=E7=94=A8=E7=BB=93=E6=9E=84=20=E6=B3=A8=E5=86=8C?= =?utf8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../zhihui/leiniao/imsl_ln/leiniao_api_at.c | 2 +- code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 38 ++++- .../zhihui/leiniao/imsl_ln/ln_api_websocket.c | 152 +++++++++++------- 3 files changed, 132 insertions(+), 60 deletions(-) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c index c86148ebb..aaed755b6 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c @@ -636,7 +636,7 @@ static uint32_t ln_ws_start_at(uint8_t *para, uint32_t paraLen, char *strCommonC VAD_UNUSED(paraLen); VAD_UNUSED(strCommonCmd); printf("[LN][WS_START]\n"); - int ret = ln_ws_start(); + int ret = ln_ws_start(NULL); if (ret != 0) { printf("[LN][WS_START] failed: %d\n", ret); diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index 74e3e9957..788da3493 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -305,10 +305,46 @@ uint32_t ln_emoji_report_all_http(const char *device_id, int group_count); /* ============================== WebSocket 客户端接口 ============================== */ -int ln_ws_start(void); + +/* WebSocket命令枚举 */ +typedef enum { + WS_CMD_UNKNOWN = 0, + WS_CMD_CHARACTER_CHANGE, + WS_CMD_CHARACTER_CONFIG_CHANGE, + WS_CMD_SLEEP_MODE_START, + WS_CMD_SLEEP_MODE_END, + WS_CMD_DEVICE_BIND, + WS_CMD_DEVICE_UNBIND, + WS_CMD_SCHEDULE_REMINDER, + WS_CMD_SCHEDULE_REMINDER_CFG, + WS_CMD_DOWNLOAD_EMOJI, + WS_CMD_DELETE_EMOJI, + WS_CMD_PING, + WS_CMD_PONG, + WS_CMD_MAX +} ws_command_t; + +/* 消息数据结构 */ +typedef struct { + char device_id[64]; + uint32_t timestamp; + char message_id[64]; + ws_command_t command; + char command_str[32]; + char *raw_json; // 原始JSON字符串,用于需要完整数据的场景 +} ws_data_msg_t; + +/* 消息处理回调函数类型 */ +typedef void (*ws_message_callback_t)(const ws_data_msg_t *data_msg, ws_command_t type); + +/* WebSocket接口函数 */ +int ln_ws_start(ws_message_callback_t callback); int ln_ws_send_text(const char *text); int ln_ws_stop(void); +int ln_ws_stop_async(void); +/* 回调函数注册接口 */ +void ln_ws_register_message_callback(ws_message_callback_t callback); #ifdef __cplusplus } diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c index 1ac24d400..555a11158 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c @@ -27,32 +27,6 @@ #define WS_STATE_CONNECTED 2 // 连接成功 /* WebSocket命令枚举 */ -typedef enum { - WS_CMD_UNKNOWN = 0, - WS_CMD_CHARACTER_CHANGE, - WS_CMD_CHARACTER_CONFIG_CHANGE, - WS_CMD_SLEEP_MODE_START, - WS_CMD_SLEEP_MODE_END, - WS_CMD_DEVICE_BIND, - WS_CMD_DEVICE_UNBIND, - WS_CMD_SCHEDULE_REMINDER, - WS_CMD_SCHEDULE_REMINDER_CFG, - WS_CMD_DOWNLOAD_EMOJI, - WS_CMD_DELETE_EMOJI, - WS_CMD_PING, - WS_CMD_PONG, - WS_CMD_MAX -} ws_command_t; - -/* 统一的消息数据结构 */ -typedef struct { - char device_id[64]; - uint32_t timestamp; - char message_id[64]; - ws_command_t command; - char command_str[32]; - char *raw_json; // 原始JSON字符串,用于需要完整数据的场景 -} ws_data_msg_t; @@ -69,6 +43,7 @@ static uint32_t g_ws_main_thread = 0; static volatile int g_ws_running = 0; static volatile unsigned int g_ws_reconnect_count = 0; /* 断线后递增,用于URL reconnect参数 */ static osMessageQueueId_t g_ws_msg_queue = NULL; +static ws_message_callback_t g_ws_message_callback = NULL; /* 消息处理回调函数 */ static void ln_ws_build_url(char *out, size_t out_size); int ln_ws_send_ping(void); @@ -76,6 +51,8 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str); static int ln_ws_parse_data_message(const char *json_str, ws_data_msg_t *data_msg); static int ln_ws_queue_data_message(const ws_data_msg_t *data_msg); static void ln_ws_free_data_message(ws_data_msg_t *data_msg); +static void ln_ws_default_message_handler(const ws_data_msg_t *data_msg, ws_command_t type); +static void ln_ws_process_message_with_callback(const ws_data_msg_t *data_msg); /* 队列创建函数 */ void ln_ws_queue_init(void) @@ -213,37 +190,8 @@ static void ln_ws_main_thread(void *arg) data_msg->device_id, data_msg->timestamp, data_msg->message_id, data_msg->command, data_msg->command_str); - // 根据命令类型进行具体处理 - switch (data_msg->command) { - case WS_CMD_PONG: - printf("[LN][WS] Processing Pong message\n"); - // 更新心跳状态、记录响应时间等 - break; - case WS_CMD_CHARACTER_CHANGE: - printf("[LN][WS] Processing CharacterChange message\n"); - break; - case WS_CMD_SLEEP_MODE_START: - printf("[LN][WS] Processing SleepModeStart message\n"); - break; - case WS_CMD_SLEEP_MODE_END: - printf("[LN][WS] Processing SleepModeEnd message\n"); - break; - case WS_CMD_DEVICE_BIND: - printf("[LN][WS] Processing DeviceBind message\n"); - break; - case WS_CMD_DEVICE_UNBIND: - printf("[LN][WS] Processing DeviceUnbind message\n"); - break; - case WS_CMD_SCHEDULE_REMINDER: - printf("[LN][WS] Processing ScheduleReminder message\n"); - break; - case WS_CMD_SCHEDULE_REMINDER_CFG: - printf("[LN][WS] Processing ScheduleReminderConfig message\n"); - break; - default: - printf("[LN][WS] Processing unknown command: %d\n", data_msg->command); - break; - } + // 使用回调函数处理消息 + ln_ws_process_message_with_callback(data_msg); // 释放消息内存 ln_ws_free_data_message(data_msg); @@ -394,8 +342,9 @@ int ln_ws_send_ping(void) /* * 启动:开启监督线程与心跳机制(心跳线程首次连接成功后会自然启动) * - 若已在运行则直接返回成功 + * - callback: 消息处理回调函数,可以为NULL使用默认处理 */ -int ln_ws_start(void) +int ln_ws_start(ws_message_callback_t callback) { if (g_ws_running) { return 0; @@ -403,6 +352,14 @@ int ln_ws_start(void) g_ws_running = 1; g_ws_reconnect_count = 0; /* 启动时从0开始 */ g_ws_connected = WS_STATE_DISCONNECTED; /* 启动时重置连接状态 */ + + // 注册回调函数 + g_ws_message_callback = callback; + if (callback != NULL) { + printf("[LN][WS] Message callback registered successfully\n"); + } else { + printf("[LN][WS] Using default message handler\n"); + } if (!g_ws_main_thread) { app_task_definition_ext_t main_task = { .attr = { @@ -519,6 +476,22 @@ const char* ln_ws_get_connection_state_string(void) } } +/* ============================ 公共回调函数接口 ============================ */ + +/** + * @brief 注册消息处理回调函数(公共接口) + * @param callback 回调函数 + */ +void ln_ws_register_message_callback(ws_message_callback_t callback) +{ + g_ws_message_callback = callback; + if (callback != NULL) { + printf("[LN][WS] Message callback registered successfully\n"); + } else { + printf("[LN][WS] Message callback unregistered\n"); + } +} + /* ============================ 统一消息解析和队列处理 ============================ */ /** @@ -687,4 +660,67 @@ static void ln_ws_free_data_message(ws_data_msg_t *data_msg) } } +/* ============================ 回调函数管理 ============================ */ + +/** + * @brief 默认消息处理器 + * @param data_msg 消息数据 + * @param type 消息类型 + */ +static void ln_ws_default_message_handler(const ws_data_msg_t *data_msg, ws_command_t type) +{ + if (!data_msg) return; + + printf("[LN][WS] Default handler: Processing %s message (type: %d)\n", data_msg->command_str, type); + + switch (type) { + case WS_CMD_PONG: + printf("[LN][WS] Default: Processing Pong message\n"); + // 更新心跳状态、记录响应时间等 + break; + case WS_CMD_CHARACTER_CHANGE: + printf("[LN][WS] Default: Processing CharacterChange message\n"); + break; + case WS_CMD_SLEEP_MODE_START: + printf("[LN][WS] Default: Processing SleepModeStart message\n"); + break; + case WS_CMD_SLEEP_MODE_END: + printf("[LN][WS] Default: Processing SleepModeEnd message\n"); + break; + case WS_CMD_DEVICE_BIND: + printf("[LN][WS] Default: Processing DeviceBind message\n"); + break; + case WS_CMD_DEVICE_UNBIND: + printf("[LN][WS] Default: Processing DeviceUnbind message\n"); + break; + case WS_CMD_SCHEDULE_REMINDER: + printf("[LN][WS] Default: Processing ScheduleReminder message\n"); + break; + case WS_CMD_SCHEDULE_REMINDER_CFG: + printf("[LN][WS] Default: Processing ScheduleReminderConfig message\n"); + break; + default: + printf("[LN][WS] Default: Processing unknown command: %d\n", type); + break; + } +} + +/** + * @brief 使用回调函数处理消息 + * @param data_msg 消息数据 + */ +static void ln_ws_process_message_with_callback(const ws_data_msg_t *data_msg) +{ + if (!data_msg) return; + + ws_command_t type = data_msg->command; + + // 如果有注册回调函数,调用它;否则使用默认处理 + if (g_ws_message_callback != NULL) { + g_ws_message_callback(data_msg, type); + } else { + ln_ws_default_message_handler(data_msg, type); + } +} + -- 2.17.1