However, when I do an OTA update, regardless of settings used in the new options in ESP-IDF 3.3, the receiving websocket task is starved of the messages arriving every 3s from the browser. After the erase, websocket messages get through to the browser every 64KB which gives a nice update to the user of progress instead of wondering whether anything is happening for a minute.
As a result, I attempt to change the netconn timeout, but it still times out at 10s. It does recover, but I'd like it not to timeout.
In the code below I print the existing value of the timeout to make sure I haven't done something stupid with the pointer, but it displays the expected 10000 or 32000 values here.
Any thoughts?
Code: Select all
//task to alter websocket web timeout from 10s to max when doing OTA update to avoid dropping connection
void task_wswebtimeout(void *pvParameters){
struct netconn** pnewconn = pvParameters;
int bits;
while(1){
bits = xEventGroupWaitBits(wifi_event_group, WSWEB_NO_TIMEOUT | WSWEB_10S_TIMEOUT, true, false, portMAX_DELAY);
if (bits & WSWEB_NO_TIMEOUT) {
ESP_LOGW(TAG, "WSWEB_NO_TIMEOUT");
ESP_LOGW(TAG, "EXISTING TIMEOUT %d", netconn_get_recvtimeout(*pnewconn));
netconn_set_recvtimeout(*pnewconn, 32000);
ESP_LOGW(TAG, "NEW TIMEOUT %d", netconn_get_recvtimeout(*pnewconn));
}
else if (bits & WSWEB_10S_TIMEOUT) {
ESP_LOGW(TAG, "WSWEB_10S_TIMEOUT");
ESP_LOGW(TAG, "EXISTING TIMEOUT %d", netconn_get_recvtimeout(*pnewconn));
netconn_set_recvtimeout(*pnewconn, 10000);
ESP_LOGW(TAG, "NEW TIMEOUT %d", netconn_get_recvtimeout(*pnewconn));
}
}
}
Code: Select all
/* Parameter is websocket port, not to be passed as stack variable hence uint16_t cast to void* to create the task.
Code shared between two websocket tasks, but unique instances.
They both use WebSocket_rx_queue but otherwise are encapsulated with their own stacks and heap structures. */
void task_WSServer(void *pvParameters) {
uint16_t port = (uint16_t)(uint32_t)pvParameters;
uint8_t wsNum = (uint8_t)(port - WS_PORT_WEB);
bool taskCreated = false;
ESP_LOGI(TAG, "port %d, wsNum %d", port, wsNum);
//connection references
struct netconn *conn, *newconn;
while(1){
//set up new TCP listener
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, port);
netconn_listen(conn);
//wait for connections
while (netconn_accept(conn, &newconn) == ERR_OK)
{
ESP_LOGI(TAG, "ws_server_netconn_serve starting on wsNum %d port %d", wsNum, port);
//tcp_nagle_disable(newconn->pcb.tcp);
if (port == WS_PORT_WEB){
netconn_set_recvtimeout(newconn, 10000);//timeout only on WS_PORT_WEB
xEventGroupSetBits(wifi_event_group, WS_CONN_PORT_9997_BIT);
if (!taskCreated) {
taskCreated = true;
xTaskCreate(task_wswebtimeout, "wswebtimeout", 2048, (void*) &newconn, 5, NULL);
}
}
ws_server_netconn_serve(wsNum, newconn);
ESP_LOGW(TAG, "ws_server_netconn_serve ended, now looping to netconn_accept");
if (port == WS_PORT_WEB) {
//stop and (re)start the webserver to clear it out and ready for the next connection
stop_webserver();
start_webserver();
xEventGroupClearBits(wifi_event_group, WS_CONN_PORT_9997_BIT);
}
}
ESP_LOGE(TAG, "netconn_accept returned error");
//close connection
netconn_close(conn);
netconn_delete(conn);
}
}