Skip to content

Commit c8dc0a3

Browse files
committed
fix(web): send ws frames from httpd's context
1 parent 6bd3aa9 commit c8dc0a3

1 file changed

Lines changed: 42 additions & 6 deletions

File tree

main/WebServerManager.cpp

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,16 +1638,52 @@ esp_err_t WebServerManager::handleWifiScan(httpd_req_t *req) {
16381638
// WebSocket Implementation
16391639
// ============================================================================
16401640

1641+
struct AsyncWsData {
1642+
httpd_handle_t server;
1643+
int fd;
1644+
httpd_ws_type_t type;
1645+
std::vector<uint8_t> payload;
1646+
};
1647+
1648+
static void send_ws_work_cb(void *arg) {
1649+
std::unique_ptr<AsyncWsData> data(static_cast<AsyncWsData *>(arg));
1650+
1651+
if (data) {
1652+
httpd_ws_frame_t ws_pkt = {};
1653+
ws_pkt.final = true;
1654+
ws_pkt.fragmented = false;
1655+
ws_pkt.type = data->type;
1656+
ws_pkt.len = data->payload.size();
1657+
ws_pkt.payload = data->payload.empty() ? nullptr : data->payload.data();
1658+
1659+
httpd_ws_send_frame_async(data->server, data->fd, &ws_pkt);
1660+
}
1661+
}
1662+
16411663
esp_err_t WebServerManager::ws_send_frame(httpd_handle_t server, int fd,
16421664
const uint8_t *payload, size_t len,
16431665
httpd_ws_type_t type) {
16441666
#ifdef CONFIG_HTTPD_WS_SUPPORT
1645-
httpd_ws_frame_t ws_pkt = {.final = true,
1646-
.fragmented = false,
1647-
.type = type,
1648-
.payload = const_cast<uint8_t *>(payload),
1649-
.len = len};
1650-
return httpd_ws_send_frame_async(server, fd, &ws_pkt);
1667+
if (!server)
1668+
return ESP_FAIL;
1669+
1670+
auto data = std::make_unique<AsyncWsData>();
1671+
data->server = server;
1672+
data->fd = fd;
1673+
data->type = type;
1674+
1675+
if (len > 0 && payload) {
1676+
data->payload.assign(payload, payload + len);
1677+
}
1678+
1679+
AsyncWsData *raw_data = data.release();
1680+
1681+
esp_err_t ret = httpd_queue_work(server, send_ws_work_cb, raw_data);
1682+
if (ret != ESP_OK) {
1683+
std::unique_ptr<AsyncWsData> cleanup(raw_data);
1684+
}
1685+
1686+
return ret;
16511687
#else
16521688
return ESP_ERR_NOT_SUPPORTED;
16531689
#endif

0 commit comments

Comments
 (0)