Vovka
Member
Суть в следующем: соединение по сокету рвется после http-запроса к сайту.
Вот создал тестовый пример:
Когда заходим по IP, есп выдает html-страничку, которае делает соединение с есп по сокету. есп раз в секунду (для наглядности) отправляет время-дату.
Все работает, пока есп не отсчитает 20 секунд (продовал и другое время) и делает http-запрос к сайту в интернете. После этого соединение по сокету обрывается!
Как это исправить?
Вот создал тестовый пример:
Код:
#define W_NAME "*****"
#define W_PASSW "*****"
#define W_SITE "test.com"
#define W_SITE_PORT 80
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
#include <Hash.h>
WebSocketsServer webSocket = WebSocketsServer(81);
void webSocketEvent(uint8_t num // IP
, WStype_t type // тип сообщения
, uint8_t *payload // сообщение
, size_t length // длина сообщения
) {
String s;
switch(type) {
case WStype_DISCONNECTED: { Serial.printf("webSocketEvent([%u]): Disconnected!\n", num); break; }
case WStype_CONNECTED: {
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("webSocketEvent([%u]): Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
webSocket.sendTXT(num, "Connected!!!"); break; }
case WStype_TEXT:{
Serial.printf("webSocketEvent([%u]): get Text: %s\n", num, payload);
if( length>6 && (strcmp((const char *)payload,"ws:ping")==0)){
Serial.printf("webSocketEvent([%u]) send Text: %s\n", num, "esp:pong" );
webSocket.sendTXT(num, "esp:pong");
break;
}
// send message to client
s = "message here: "; s.concat( (const char *)payload, length ); webSocket.sendTXT(num, s);
// webSocket.broadcastTXT("message here"); // send data to all connected clients
break;
}
case WStype_BIN: {
Serial.printf("webSocketEvent([%u]): get binary length: %u\n", num, length);
hexdump(payload, length);
// send message to client
webSocket.sendBIN(num, payload, length);
break;
}
}
}
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
#include <ESP8266WebServer.h>
ESP8266WebServer HTTP(80);
//#include <ESP8266HTTPUpdateServer.h> // для обновления через WEB
//ESP8266HTTPUpdateServer httpUpdater;
#include <ESP8266HTTPClient.h>
HTTPClient http;
#include "web.h"
void handleNotFound(){
String s;
s = FPSTR(_htm_test);
HTTP.send(200, "text/html", s );
}
static bool b1sec = false;
static bool b20sec = false;
static os_timer_t timer1s;
static char count20s = 20;
void timer1s_func()
{
b1sec = true;
if( !b20sec ) {
if( count20s ) count20s--;
if( !count20s ) { count20s = 20; b20sec = true; }
}
}
void setup()
{
Serial.begin(19200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for(uint8_t t = 5; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP( W_NAME, W_PASSW );
WiFi.config(IPAddress(192, 168, 1, 254), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0));
Serial.print( "SETUP(). Go connect router" );
while( WiFiMulti.run() != WL_CONNECTED ) {
Serial.print("."); delay(1000);
}
Serial.print(" OK. IP="); Serial.println( WiFi.localIP() );
// httpUpdater.setup(&HTTP, "/upd", "admin", "admin" ); // для ОТА
HTTP.onNotFound(handleNotFound);
// Запускаем HTTP сервер
HTTP.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
// запустим таймер 1сек
os_timer_disarm(&timer1s);
os_timer_setfn(&timer1s, (os_timer_func_t *)&timer1s_func, NULL);
os_timer_arm(&timer1s, 1000, 1); // 1000 миллисекунд=1cек, 1 - многократно. 0 -однократно.
}
void loop()
{
String s;
// ожидание WiFi соединения
if( WiFiMulti.run() == WL_CONNECTED ) {
HTTP.handleClient();
webSocket.loop();
if( b1sec ) {
time_t t;
tm *pt;
t = time(nullptr); pt = localtime(&t);
s = String( pt->tm_hour ); s += ":";
s += String( pt->tm_min ); s += ":";
s += String( pt->tm_sec ); s += " ";
s += String( pt->tm_mday ); s += ".";
s += String( pt->tm_mon+1); s += ".";
s += String( pt->tm_year );
webSocket.broadcastTXT( s ); // все подключившимся
Serial.println( s );
b1sec = false;
}
if( b20sec ) {
Serial.print("[HTTP] begin...\n");
if( http.begin( W_SITE, W_SITE_PORT, "/esp.php") ) {
Serial.print("[HTTP] GET...\n");
int httpCode = http.GET();
if( httpCode ) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// файл найден на сервере
if( httpCode == 200 ) {
String payload = http.getString();
Serial.println( payload );
webSocket.broadcastTXT( payload );
}
} else {
Serial.print("[HTTP] GET... failed, no connection or no HTTP server\n");
}
http.end();
}
b20sec = false;
}
}
}
Код:
const char _htm_test[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251'>
<meta http-equiv='Content-Language' content='ru'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<meta http-equiv='pragma' content='no-cache'>
<meta http-equiv='cache-control' content='no-cache'>
<title>TEST</title>
<script language='javascript'>
function startWebsocket() {
var adr='ws://192.168.1.254:81/';
var connection = new WebSocket(adr);
var wsstat=-1; //Статус подключения
var wsp=0;
var idd=document.getElementById('lans');
idd.innerHTML='Попытка подключения...';
function wsping(){
if(wsstat!=connection.readyState){
wsstat=connection.readyState;
switch(wsstat){
case 0: idd.innerHTML='Соединение ещё не открыто';break;
case 1: idd.innerHTML=''; break;
case 2: idd.innerHTML='Соединение в процессе закрытия';break;
case 3: idd.innerHTML='Соединение закрыто или не может открыться';break;
}
}
connection.send('ws:ping');
wsp=setTimeout(wsping, 2500);
}
connection.onopen = function () {
idd.innerHTML='подключено';
wsp=setTimeout(wsping, 2500);
};
connection.onclose = function(evt) {
if(wsp)clearTimeout(wsp);wsp=0;wsstat=0;
idd.innerHTML= 'WebSocket CLOSED: ('+evt.code+') '+evt.reason;
connection=0;setTimeout(startWebsocket, 5000);
};
connection.onerror = function (error) {
idd.innerHTML = 'WebSocket Error: ' + error.message;
};
connection.onmessage = function (evt) {
var data=evt.data;
if(typeof(data)=='string'&&data!=='esp:pong') idd.innerHTML=data;
clearTimeout(wsp);wsp=setTimeout(wsping, 2500);
};
}
window.onload=function(){startWebsocket()};
</script>
</head><body>
<h3>T е с т</h3>
<span id='lans'> </span>
</body></html>
)rawliteral";
Когда заходим по IP, есп выдает html-страничку, которае делает соединение с есп по сокету. есп раз в секунду (для наглядности) отправляет время-дату.
Все работает, пока есп не отсчитает 20 секунд (продовал и другое время) и делает http-запрос к сайту в интернете. После этого соединение по сокету обрывается!
Как это исправить?