Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By kenn
#30384
NardJ wrote:Is there a streaming protocol which can be used within a browser? (My search on internet didn't turn anything up, but maybe I choose the wrong keywords for my search.)


Google "real-time data streaming to a web browser". A few different possibilities show up.
User avatar
By torntrousers
#30398 I've been playing around a little with some limited performance testing of the ESP server and client. I think it should be able to do more than 10 requests per second, but i think there may be some bugs in the ESP code that can slow things down. Don't know how related this is to your question but i'll put it out here as FYI to see if anyone has any ideas:

One thing is with the provided WiFiServer - HelloServer example, running that on an ESP-12 and calling it from a Java program another PC on my local network it takes about 330 milliseconds per request (testing a similar Hello server running on node.js on another PC on the local network does it in about 8 millisecond so its not the network thats slow). It also doesn't vary much running the ESP at 80MHz or 160MHz so its not the CPU thats slowing it down.

However, changing the Java client to do an HTTP HEAD instead of a GET then the requests to the ESP take only about 25 milliseconds.

Updating the ESP HelloServer to do a Serial.print of millis() around the line
Code: Select allserver.send(200, "text/plain", "hello from esp8266!\r\n");
shows that takes nearly 300ms for the GET but only 4ms for the HEAD.

So thats a bit odd, it shouldn't need hundreds of milliseconds to be sending a couple of dozen extra characters. So fixing whatever is going on there could get it up to around 40 requests per second.

There's also something funny in the ESP WiFiClient. If you do two client.print's to send a request then the first print takes around 300 milliseconds. Eg this:
Code: Select all  client.print("HEAD /");
  client.print(" HTTP/1.1\r\nHost: 192.168.1.96\r\nConnection: close\r\n\r\n");


the first print takes hundreds of milliseconds and the second print just a few milliseconds, where as combining the request into a single print like this:

Code: Select all  client.print("HEAD / HTTP/1.1\r\nHost: 192.168.1.96\r\nConnection: close\r\n\r\n");


takes just a few milliseconds.
User avatar
By NardJ
#30435 Good to know higher speeds are possible and thanks for the search keywords! (Don't know why this time I got some usefull results.)

I found and tried 2 possible streaming solutions. Both have twice the update speeds of the 'simple' xmlhttp code in previous post:
1) XMLHttp streaming (18 fps / data updates per second)
2) Server Sent Events (16 fps / data updates per second)
These update speeds are constant at least up until sending 1kB of data. I think 16fps is about the minimum speed for video-like updates.

Seeing the possible data size I can send without an impact on the update speed, I think still higher update speeds should be possible using streaming. Any other ideas to try?

XMLHttp Streaming:
Code: Select all#include <ESP8266WiFi.h>

const char* ssid = "...";
const char* password = "...";

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

const char html[]=
  "<html><head>\n"
  "<meta name='viewport' content='width=device-width, initial-scale=1' />\n"
  "<meta http-equiv='Cache-Control' content='no-cache, no-store, must-revalidate' />\n"
  "<meta http-equiv='Pragma' content='no-cache' />\n"
  "<meta http-equiv='Expires' content='0' />\n"
  "<script src='script.js'></script>\n"
  "</head>\n"
  "<body>\n<h1 style='font-family:Lucida Console;font-size:32px'>Data request per second</h1>\n"
  "<div id='fps' style='background-color:#FFFFAA;border:1px solid black;width:112px;height:24px;text-align:center;line-height:22px;font-size:12px;'>?? fps</div>"
  "<DIV id='Log' style='background-color:#FFFFAA;width:378px;height:80px;border:1px solid black;font-family:Lucida console;font-size:10px;padding:2px;overflow:auto;'></div>\n" 
  "</body></html>\n";

const char js[]=   
    "var interval;\n"
    "var xmlhttp=new XMLHttpRequest();\n"   
    "function printLog(msg){var log=document.getElementById('Log');log.innerHTML=log.innerHTML+msg+'<br>';log.scrollTop = log.scrollHeight}\n"       
    "document.addEventListener('DOMContentLoaded',init,false);\n"
    "var fC=0;\n"
    "setInterval(updateFPS,1000);\n"
    "function updateFPS(){\n"
    "  var fT = document.getElementById('fps');\n"
    "  fT.innerHTML=fC+ ' fps';\n"
    "  fC=0;"
    "}\n"   
    "function init(){\n"   
    "  var len = 0;\n"   
    "  xmlhttp.onreadystatechange = function() {\n"   
    "    if (xmlhttp.status == 200 && xmlhttp.readyState >=3) {\n"   
    "      var text = xmlhttp.responseText;\n"   
    "      text = text.substr(len, text.length-len);\n"   
    "      len = text.length;\n"   
    "      printLog(text);\n"
    "      fC++;\n"       
    "    }\n"   
    "  }\n"   
    "  xmlhttp.open('GET', '/xmlhttp.esp',true);\n"       
//    "  xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');\n"
    "  xmlhttp.send();\n"   
    "}\n"
;


void setup() {
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

unsigned long t=0;

void loop() {
  //http://stackoverflow.com/questions/3880381/xmlhttprequest-responsetext-while-loading-readystate-3-in-chrome

  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) return;
  Serial.print("Client found: ");
  Serial.println(client);
 
  // Wait until the client sends some data
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println("url: "+req);
  client.flush();
 
  // Match the request
  String ret="";
  if (req.equals("GET / HTTP/1.1")) {
    ret= "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE html>";
    ret=ret+html;
    client.print(ret);
    delay(1);
  }
  if (req.equals("GET /script.js HTTP/1.1")) {
    ret= "HTTP/1.1 200 OK\r\nContent-Type: application/javascript\r\n\r\n";
    ret=ret+js;
    client.print(ret);
    delay(1);
  }
  if (req.equals("GET /xmlhttp.esp HTTP/1.1")) {
    ret = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\n\r\n";
    ret=ret+"data: ";
    ret=ret+t;
    ret=ret+"\r\n";
    client.print(ret);
    while (t<100000){
      t++;
      ret="Timer is: ";
      ret=ret+t;
      ret=ret+"\r\n";
      client.print(ret);
      //Serial.println(t);
      yield;
    }
  }
   
  delay(1);
  Serial.println("Client disconnected");

  // The client will actually be disconnected
  // when the function returns and 'client' object is detroyed
}


Server Sent Events:
Code: Select all#include <ESP8266WiFi.h>

const char* ssid = "...";
const char* password = "...";

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

const char html[]=
  "<html><head>\n"
  "<meta name='viewport' content='width=device-width, initial-scale=1' />\n"
  "<meta http-equiv='Cache-Control' content='no-cache, no-store, must-revalidate' />\n"
  "<meta http-equiv='Pragma' content='no-cache' />\n"
  "<meta http-equiv='Expires' content='0' />\n"
  "<script src='script.js'></script>\n"
  "</head>\n"
  "<body>\n<h1 style='font-family:Lucida Console;font-size:32px'>Data request per second</h1>\n"
  "<div id='fps' style='background-color:#FFFFAA;border:1px solid black;width:112px;height:24px;text-align:center;line-height:22px;font-size:12px;'>?? fps</div>"
  "<DIV id='Log' style='background-color:#FFFFAA;width:378px;height:80px;border:1px solid black;font-family:Lucida console;font-size:10px;padding:2px;overflow:auto;'></div>\n" 
  "</body></html>\n";

const char js[] =   
    "function printLog(msg){var log=document.getElementById('Log');log.innerHTML=log.innerHTML+msg+'<br>';log.scrollTop = log.scrollHeight}\n"   
    "document.addEventListener('DOMContentLoaded',initCanvas,false);\n"
    "var fC=0;\n"
    "var source;\n"
    "setInterval(updateFPS,1000);\n"
    "function updateFPS(){\n"
    "  var fT = document.getElementById('fps');\n"
    "  fT.innerHTML=fC+ ' fps';\n"
    "  fC=0;"
    "}\n"   
    "function initCanvas(){\n"   
    "  printLog('initCanvas');\n"
    "  source = new EventSource('streamt.esp');\n"
    "  source.onmessage = function(event) {refresh(event.data);};\n"
//    "  source.onmessage = function(event) {printLog('refresh');};\n"
    "}\n"
    "function refresh(data){\n"
    "    printLog(data);\n"
    "    fC++;\n"
    "}\n"
    ;

void setup() {
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());

}

unsigned long t=0;

void loop() {
  //http://www.w3schools.com/html/html5_serversentevents.asp
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) return;
  Serial.print("Client found: ");
  Serial.println(client);
 
  // Wait until the client sends some data
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println("url: "+req);
  client.flush();
 
  // Match the request
  String ret="";
  if (req.equals("GET / HTTP/1.1")) {
      ret="HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE html>";
      ret=ret+html;
      client.print(ret);   
      delay(1);
  }
  if (req.equals("GET /script.js HTTP/1.1")) {
      ret="HTTP/1.1 200 OK\r\nContent-Type: application/javascript\r\n\r\n";
      ret=ret+js;
      client.print(ret);   
      delay(1);
  }
  if (req.equals("GET /streamt.esp HTTP/1.1")) {
    client.print(ret);
    while (true){ 
      ret = "HTTP/1.1 200 OK\r\nContent-Type: text/event-stream\r\nCache-Control: no-cache\r\n\r\n";
      ret=ret+"data: ";
      ret=ret+t;
      ret=ret+"\r\n";
      client.print(ret);   
      client.flush();
      t=t+1;
      //delay(1);
      Serial.println(t);
      yield();
    }
  }
  Serial.println("Client disconnected");

  // The client will actually be disconnected
  // when the function returns and 'client' object is detroyed
}
User avatar
By pvvx
#30447 JMeter Throughput 8826,775/minute (228.14/sec) HTTP GET aesp8266/heap.xml (276 bytes) (to 63 simultaneous open connections). Not Arduino:
Jmeter38.gif
Jmeter39.gif
Jmeter41.gif

http://esp8266.ru/forum/threads/razrabo ... post-11018
You do not have the required permissions to view the files attached to this post.