Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP8266 unstable POST/GET requests #3282

Closed
marcek opened this issue May 23, 2017 · 3 comments
Closed

ESP8266 unstable POST/GET requests #3282

marcek opened this issue May 23, 2017 · 3 comments

Comments

@marcek
Copy link

marcek commented May 23, 2017

Basic Infos

Hardware

Hardware: WeMos D1 mini V2 ESP8266 E12
Core Version: 2.3.0

Description

Hi there,
I have a webserver running on my WeMos which provides a simple HTML page. It communicates with the board through AJAX in order to get information about WIFI. I've checked already various issues on github but I'm still a bit confused how to correctly send a response to an AJAX call.

I read about few practices like enabling chunk mode by using setContentLength(CONTENT_LENGTH_UNKNOWN) and sendContent() functions in case content length is unknown and just send() function otherwise. Even when I follow those rules sometimes I get empty response immediately and it seems like request was all of sudden interrupted.

My doubts

  1. Why do we need to use chunk mode in some cases ? is it because of limited resources and weakness of web server on esp8266 ?
  2. Is it possible to just respond to an ajax call when WiFi.begin() or WiFi.scanNetworks() finish their jobs or:
    a) do I need to implement some pooling, send multiple ajax requests and wait for a proper response ?
    b) The only way is chunk mode ?

My getNetworkStatus(), getNetworks() and connectToWifi() are pretty simple. Can you maybe point me into the right direction how to implement them correctly ?

Sketch

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>

char ssid[32] = "";
char password[32] = "";
ESP8266WebServer server(80);

void getNetworkStatus() {
  server.send(200, "application/json", "{\"status\": \"" + String(WiFi.status()) + "\", \"network\": \""+ WiFi.SSID() + "\"}");
}

void getNetworks() {
  String str;
  int n = WiFi.scanNetworks();

  for(int i=0; i<n; i++) {
    str += "\"" + WiFi.SSID(i) + "\"";
    if(i < n-1) { str += ","; }
  }

  Serial.print("Networks: ");
  Serial.println(str);
  server.send(200, "application/json", "{\"networks\": [" + str + "] }");
}

void connectToWifi() {
  server.arg("ssid").toCharArray(ssid, sizeof(ssid)-1);
  server.arg("password").toCharArray(password, sizeof(password)-1);

  WiFi.disconnect();
  WiFi.begin(ssid, password);
  WiFi.waitForConnectResult();

 server.send(200, "application/json", "{\"status\": \"connecting\" }");
}

void setup() {
  Serial.begin(9600);
  SPIFFS.begin();

  WiFi.softAP("wemosd1");

  server.serveStatic("/", SPIFFS, "/home.html");
  server.on("/connect", connectToWifi);
  server.on("/status", getNetworkStatus);
  server.on("/networks", getNetworks);

  server.serveStatic("/styles.css", SPIFFS, "/styles.css");
  server.serveStatic("/jquery-3.2.1.min.js", SPIFFS, "/jquery-3.2.1.min.js");
  server.serveStatic("/scripts.js", SPIFFS, "/scripts.js");
  server.serveStatic("/spinner.svg", SPIFFS, "/spinner.svg");
  server.begin();
}

void loop() {
   server.handleClient();
}

scripts.js from home.html

  $('.scan-networks').on('click', function(event) {
    event.preventDefault();

    $.get('/networks', function(data) {
      console.log(data);
    });
  });

  $('.network-form').on('submit', function(event) {
    event.preventDefault();

    $.post('/connect', $(this).serialize())
      .done(function(response) {
        console.log(response);
      });
  })

  // ...
@marcek
Copy link
Author

marcek commented May 24, 2017

Doesn't matter chunk mode or not. ESP8266 doesn't return full responses to HTTP calls in two cases:

  1. WiFi.waitForConnectResult() is in use. Without it I get a full response:
void connectToWifi() {
  server.setContentLength(CONTENT_LENGTH_UNKNOWN);
  server.send(200, "text/plain", "Connecting...");

  WiFi.disconnect();
  WiFi.begin("ssid", "password");
  WiFi.waitForConnectResult();

  // Never comes back as a response to AJAX call when WiFi.waitForConnectResult() is in use
  server.sendContent("Done!");
  server.sendContent("");
  server.client().stop();

  // See it in serial monitor no error occurs 
  Serial.println("Done!");
}

Works correctly. The only case I don't get a full response is when it's called right after WiFi.begin() fails to connect.

void getNetworks() {
  server.setContentLength(CONTENT_LENGTH_UNKNOWN);
  server.send(200, "text/plain", "Scanning...");

  String str;
  int n = WiFi.scanNetworks();

  for(int i=0; i<n; i++) {
    str += "\"" + WiFi.SSID(i) + "\"";
    if(i < n-1) { str += ","; }
  }

  // When called right after WiFi.begin() fails to connect, never comes back as a response to AJAX call
  server.sendContent("{\"networks\": [" + str + "] }");
  server.sendContent("");
  server.client().stop();

  // See it in serial monitor no error occurs 
  Serial.println("Done!");
}

Any suggestions ?

@igrr
Copy link
Member

igrr commented May 24, 2017

This is related to the fact that STA will switch to the channel of the AP it is trying to connect to, and SoftAP will have to switch to the same channel. So the client (PC or smartphone connected to the SoftAP) will have to reconnect to the SoftAP on its new channel. In most cases this causes TCP connections to be reset.

@marcek
Copy link
Author

marcek commented May 24, 2017

Thank you for the answer. That problem was already discussed #119. Everything is clear now.

@marcek marcek closed this as completed May 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants