Алексей.
Active member
Решил немножко проверить работу ESP8266WebServer.
Добавил только обработчик корневого url, в котором на запрос клиента отвечаю количеством обработанных запросов, просто вызываю server.send(200, "text/plain", message);
Со стороны ПК запустил скриптик (в двух экземплярах) в котором используя curl выполнил 100000 запросов, esp честно отсчитал 200К запросов и довольно быстро.
Немножко усложнил опыт, опять запускаю скрипт и пока он выполняется, соединяюсь с тем-же сервером, отправляю запрос получаю ответ и продолжаю оставаться в соединении до тех пор пока сервер сам не разорвет соединение, сервер через 2-е секунды разрывает соединение.
Почему то скрипт работающий рядом начал тормозить.
Заглянул в исходники, обнаружил потенциально опасное место в методе handleClient.
В пока запрос не принят полностью статус обработки имеет значение HC_WAIT_READ
если запрос принят полностью, вызывается обработчик этого запроса и если клиент ещё в соединении - статус переводится в HC_WAIT_CLOSE, как раз мой случай, клиент получил ответ и не торопится разрывать соединение с сервером.
Далее для значения статуса HC_WAIT_CLOSE очень интересный код
т.е. пока не прошло HTTP_MAX_CLOSE_WAIT (константа 2000) миллисекунд с последнего изменения статуса, продолжаем сохранять соединение.
В случае перехода millis через максимальное значение, соединение будет сохраняться очень долго и запросы других клиентов не будут обрабатываться.
Непонятно для чего ожидать разрыва соединения со стороны клиента.
Почему после обработки запроса сервер не разрывает соединение сразу, а ждет разрыв соединения со стороны клиента, клиент может вообще никогда не разрывать соединение.
Добавил только обработчик корневого url, в котором на запрос клиента отвечаю количеством обработанных запросов, просто вызываю server.send(200, "text/plain", message);
Со стороны ПК запустил скриптик (в двух экземплярах) в котором используя curl выполнил 100000 запросов, esp честно отсчитал 200К запросов и довольно быстро.
Немножко усложнил опыт, опять запускаю скрипт и пока он выполняется, соединяюсь с тем-же сервером, отправляю запрос получаю ответ и продолжаю оставаться в соединении до тех пор пока сервер сам не разорвет соединение, сервер через 2-е секунды разрывает соединение.
Почему то скрипт работающий рядом начал тормозить.
Заглянул в исходники, обнаружил потенциально опасное место в методе handleClient.
Код:
if (_currentClient.connected() || _currentClient.available()) {
switch (_currentStatus) {
case HC_NONE:
// No-op to avoid C++ compiler warning
break;
case HC_WAIT_READ:
// Wait for data from client to become available
if (_currentClient.available()) {
if (_parseRequest(_currentClient)) {
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT);
_contentLength = CONTENT_LENGTH_NOT_SET;
_handleRequest();
if (_currentClient.connected()) {
_currentStatus = HC_WAIT_CLOSE;
_statusChange = millis();
keepCurrentClient = true;
}
}
} else { // !_currentClient.available()
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
keepCurrentClient = true;
}
callYield = true;
}
break;
case HC_WAIT_CLOSE:
// Wait for client to close the connection
if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) {
keepCurrentClient = true;
callYield = true;
}
}
}
если запрос принят полностью, вызывается обработчик этого запроса и если клиент ещё в соединении - статус переводится в HC_WAIT_CLOSE, как раз мой случай, клиент получил ответ и не торопится разрывать соединение с сервером.
Далее для значения статуса HC_WAIT_CLOSE очень интересный код
Код:
if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) {
keepCurrentClient = true;
callYield = true;
}
В случае перехода millis через максимальное значение, соединение будет сохраняться очень долго и запросы других клиентов не будут обрабатываться.
Непонятно для чего ожидать разрыва соединения со стороны клиента.
Почему после обработки запроса сервер не разрывает соединение сразу, а ждет разрыв соединения со стороны клиента, клиент может вообще никогда не разрывать соединение.