1. 优化了cpp_json的内容,使其更modern
2. 稍微优化了一下系统配置类 3. 增加了系统版本号,便于区分系统版本,方便OTA 4. 重写OTA的逻辑,完成了Cpp的OTA封装,测试通过
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
// 静态成员初始化
|
||||
WebSocketManager* WebSocketManager::instance = nullptr;
|
||||
std::mutex WebSocketManager::instance_mutex;
|
||||
std::string WebSocketManager::sn = SYS_CONF_JSON().loadSN(); // 获取SN(同时也能初始化文件系统,如果还没有初始化这个文件系统的话)
|
||||
std::string WebSocketManager::sn = SysConfJson::getInstance()->loadSN(); // 获取SN(同时也能初始化文件系统,如果还没有初始化这个文件系统的话)
|
||||
|
||||
// 标签用于日志
|
||||
static const char* TAG = "WebSocketManager";
|
||||
@@ -72,15 +72,15 @@ bool WebSocketManager::initialize(const WebSocketConfig& ws_config) {
|
||||
this, &wifi_instance);
|
||||
|
||||
// 启动发送线程
|
||||
threads_running = true;
|
||||
|
||||
ThreadConfig thread_config;
|
||||
thread_config.name = "WS_Send";
|
||||
thread_config.stack_size = 4096;
|
||||
|
||||
send_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::sendThread);
|
||||
|
||||
// 只在线程未运行时启动发送线程
|
||||
if (!send_thread.joinable()) {
|
||||
threads_running = true;
|
||||
ThreadConfig thread_config;
|
||||
thread_config.name = "WS_Send";
|
||||
thread_config.stack_size = 4096;
|
||||
send_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::sendThread);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,17 +118,24 @@ bool WebSocketManager::connect() {
|
||||
}
|
||||
|
||||
// 启动重连和心跳线程
|
||||
ThreadConfig thread_config;
|
||||
thread_config.name = "WS_Reconnect";
|
||||
thread_config.stack_size = 3072;
|
||||
// 只有在线程未运行时才启动新线程
|
||||
if (!reconnect_thread.joinable()) {
|
||||
ThreadConfig thread_config;
|
||||
thread_config.name = "WS_Reconnect";
|
||||
thread_config.stack_size = 3072;
|
||||
|
||||
reconnect_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::reconnectThread);
|
||||
reconnect_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::reconnectThread);
|
||||
}
|
||||
|
||||
thread_config.name = "WS_Heartbeat";
|
||||
heartbeat_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::heartbeatThread);
|
||||
if (!heartbeat_thread.joinable()) {
|
||||
ThreadConfig thread_config;
|
||||
thread_config.name = "WS_Heartbeat";
|
||||
thread_config.stack_size = 3072;
|
||||
|
||||
heartbeat_thread = ThreadManager::createMemberThread(thread_config, this,
|
||||
&WebSocketManager::heartbeatThread);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -147,25 +154,21 @@ void WebSocketManager::disconnect() {
|
||||
}
|
||||
}
|
||||
|
||||
bool WebSocketManager::sendJson(cJSON* json) {
|
||||
bool WebSocketManager::sendJson(const cppjson::Json& json) {
|
||||
if (!connected) { // 检查连接状态
|
||||
ESP_LOGE(TAG, "Not connected, cannot send data");
|
||||
cJSON_Delete(json);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* json_str = cJSON_PrintUnformatted(json); // 将JSON对象转换为字符串
|
||||
cJSON_Delete(json); // 释放JSON对象
|
||||
|
||||
if (!json_str) { // 检查转换结果
|
||||
std::string json_str = json.dump(); // 序列化 JSON
|
||||
if (json_str.empty() || json_str == "null") { // 检查序列化结果
|
||||
ESP_LOGE(TAG, "Failed to stringify JSON");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(queue_mutex); // 锁定队列
|
||||
send_queue.emplace(json_str); // 添加到队列
|
||||
free(json_str); // 释放json_str的内存
|
||||
|
||||
{ // 临界区
|
||||
std::lock_guard<std::mutex> lock(queue_mutex);
|
||||
send_queue.emplace(std::move(json_str)); // 移动进队列,零拷贝
|
||||
}
|
||||
queue_cv.notify_one(); // 通知发送线程
|
||||
return true;
|
||||
}
|
||||
@@ -241,7 +244,7 @@ void WebSocketManager::websocketEventHandler(void* handler_args, esp_event_base_
|
||||
}
|
||||
break;
|
||||
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
case WEBSOCKET_EVENT_ERROR: // 错误事件
|
||||
ws_instance->connected = false;
|
||||
ws_instance->connecting = false;
|
||||
|
||||
@@ -257,20 +260,13 @@ void WebSocketManager::websocketEventHandler(void* handler_args, esp_event_base_
|
||||
}
|
||||
|
||||
void WebSocketManager::handleReceivedData(const char* data, const int len) const {
|
||||
// 尝试解析JSON
|
||||
if (cJSON* json = cJSON_ParseWithLength(data, len)) {
|
||||
// 成功解析为JSON
|
||||
if (json_callback) {
|
||||
json_callback(json);
|
||||
} else {
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
} else {
|
||||
// 不是JSON格式,作为原始数据处理
|
||||
std::string message(data, len);
|
||||
if (event_callback) {
|
||||
event_callback(WebSocketEvent::DATA_RECEIVED, message);
|
||||
}
|
||||
// 解析JSON
|
||||
cppjson::Json json = cppjson::Json::parse(std::string(data, len)); // 失败会得到空 Json
|
||||
if (!json.isNull()) { // 解析成功
|
||||
if (json_callback) json_callback(json);
|
||||
} else { // 解析失败,当原始文本处理
|
||||
if (event_callback)
|
||||
event_callback(WebSocketEvent::DATA_RECEIVED, std::string(data, len));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +274,7 @@ void WebSocketManager::reconnectThread() {
|
||||
while (threads_running) {
|
||||
if (!connected && config.auto_reconnect &&
|
||||
(config.max_reconnect_attempts == 0 ||
|
||||
reconnect_attempts < config.max_reconnect_attempts)) {
|
||||
reconnect_attempts < config.max_reconnect_attempts)) { // 检查重连条件
|
||||
|
||||
// 检查WiFi连接
|
||||
if (!wifi->isWifiConnect()) {
|
||||
@@ -297,7 +293,7 @@ void WebSocketManager::reconnectThread() {
|
||||
ESP_LOGE(TAG, "Reconnection attempt failed");
|
||||
}
|
||||
}
|
||||
|
||||
// sleep
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(config.reconnect_interval));
|
||||
}
|
||||
}
|
||||
@@ -306,11 +302,10 @@ void WebSocketManager::heartbeatThread() {
|
||||
while (threads_running) {
|
||||
if (connected && config.heartbeat_interval > 0) { // 如果处于连接状态且心跳间隔大于0
|
||||
// 发送心跳消息
|
||||
cJSON* heartbeat = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(heartbeat, "type", "heartbeat");
|
||||
cJSON_AddNumberToObject(heartbeat, "timestamp", static_cast<double>(esp_log_timestamp()));
|
||||
|
||||
sendJson(heartbeat);
|
||||
cppjson::Json hb = cppjson::Json::object();
|
||||
hb.set("type", cppjson::Json("heartbeat"))
|
||||
.set("timestamp", cppjson::Json(esp_log_timestamp()));
|
||||
sendJson(hb); // 已经重载好了,直接塞
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(config.heartbeat_interval));
|
||||
} else { // 否则就让出CPU
|
||||
@@ -364,14 +359,18 @@ bool WebSocketManager::createWebSocketClient() {
|
||||
|
||||
// 处理sn码逻辑
|
||||
// 一般情况下sn码会在开机的时候从flash当中读出,因此此处判断是否为空
|
||||
sn = SysConfJson::getInstance()->loadSN(); // 再读一次sn码
|
||||
if (!sn.empty()) { // 如果sn码不为空
|
||||
// 则在头部加入sn码提交
|
||||
esp_websocket_client_append_header(client, "sn", sn.c_str());
|
||||
esp_websocket_client_append_header(client, "X-SN", sn.c_str());
|
||||
// 同时在头部加入mac码和芯片序列号,方便服务端做验证
|
||||
esp_websocket_client_append_header(client, "X-MAC", ToolsClass::getChipMAC().c_str());
|
||||
esp_websocket_client_append_header(client, "X-CHIP-ID", ToolsClass::getChipSerialNumber().c_str());
|
||||
}
|
||||
else {
|
||||
// 否则在头部加入mac码和芯片序列号
|
||||
esp_websocket_client_append_header(client, "mac", ToolsClass::getChipMAC().c_str());
|
||||
esp_websocket_client_append_header(client, "chip_id", ToolsClass::getChipSerialNumber().c_str());
|
||||
// 如果sn码为空,设备可能存在问题
|
||||
ESP_LOGE(TAG, "SN is empty, please check your device");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user