• It looks like there's a problem with servers not getting cleaned up when the board is reset (for example, when you click "send to Espruino" in the IDE):

    >process.version
    ="1v99"
    >process.env
    ={
      "VERSION": "1v99",
      "GIT_COMMIT": "f0d66ba",
      "BOARD": "ESP32",
      "FLASH": 0, "RAM": 524288,
      "SERIAL": "30aea40f-0074",
      "CONSOLE": "Telnet",
      "MODULES": "Flash,Storage,fs," ... "r,crypto,neopixel",
      "EXPTR": 1073485304 }
    
    

    First time I upload and try to fire up the server, it works. The second time:

    ERROR: Socket bind failed
    Uncaught InternalError: Unable to create socket
     at line 11 col 60
    ...(onPageRequest).listen(7348);
    

    It isn't clear to me yet exactly what the key factor is that makes this fail, but the code below readily reproduces it for me. Upload code once.

    Request in browser:
    (board IP address):7348/status?un=testuser&pw=testpass

    Upload code again. Watch for error in console.

    var http = require("http");
    
    
    
    function startup() {
    	E.setTimeZone(-5);
    	fetchTime();
        require("http").createServer(onPageRequest).listen(7348);
    }
    
    function fetchTime() {
    	require("http").get("http://drazzy.com/time.shtml", function(res) {
      		var contents = "";
      		res.on('data', function(data) { contents += data; });
      		res.on('close', function() { setTime(contents); });
    	}).on('error', function(e) {
      		console.log("ERROR", e);
    	});
    }
    
    var CORS={'Access-Control-Allow-Origin':'*'};
    // Network
    
    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      var resu=0;
      if (a.pathname=="/favicon.ico") {
        resu=404;
      } else {
        resu = handleCmd(a.pathname,a.query,res);
      }
      if (resu > 0) {
      	  res.writeHead(resu,CORS);
      	  if (resu==200) {res.write('{"error":false,"code":200,"text":"OK"}');}
      	  else if (resu==404) {res.write('{"error":true,"code":404,"text":"Not Found"}');}
      	  else if (resu==403) {res.write('{"error":true,"code":403,"text":"Unauthorized Client"}');}
      	  else if (resu==400) {res.write('{"error":true,"code":400,"text":"Bad Request"}');}
      } else if (resu===0) {
      	  res.writeHead(500,CORS);
      	  res.write('{"error":true,"code":500,"text":"Unknown Error"}');
      }
      res.end();
    }
    
    
    function handleCmd(path,query,res) {
    	console.log(path);
    	console.log(query);
    	if (query.un!="testuser" || query.pw!="testpass") { 
    		return 403;
    	}
    	if (path=="/status") {
    		res.writeHead(200,CORS);
    		res.write(JSON.stringify(cs));
            return -1;
    	} else {
    		return 404;
    	}
    }
    
    var cs={ //cs=Current State
    	DoorUp:0,
    	DoorDown:0,
    	Fridge:0,
    	Humidity:null,
    	Temperature:null,
    	Pressure:null,
    	Light:null
    };
    cs.Fargo=new Uint8Array(8);
    
    function onInit() {
    	setTimeout("startup()",5000);
    }
    onInit();
    

    Powercycling the board fixes it.

    Also, sometimes when I click send to Espruino, the following is printed to console:

    
    >WARNING: --- gap_setScan 0
    WARNING: Scan stop failed
    WARNING: set rssi scan not implemeted yet
    WARNING: has central connection not implemented yet
    

    Much thanks to everyone for all the work they've put into the ESP32 support.

  • The issue is the the build is compiled with 10 sockets.
    When you reset, the sockets are not closed. Part of the reason for this, is one of the sockets was the telnet server socket - you would loose your connection to the board.

    If you saved the result of you your server connect as a global:

    var server=require("http").createServer(onPageReque­st).listen(7348);

    Then before the reset - you could do server.close()

    This will shut down the connect and close the socket.

    By the way, are using using a telnet connection? It is so much faster than the com port connection.

    Oh - and your call to get the time - rather than have a page that returns the time - you can get the time out of the header..

  • When you reset, the sockets are not closed.

    Something seems odd there - if you call reset() it should call jswrap_net_kill which should shut all the open sockets (except the Telnet one, because it's handled separately). It works on ESP8266, so I think something might be broken on the ESP32 port.

  • Following the calls from jswrap_net_kill it ends up here in the ESP32 case - so it has been implemented, so I think something else is going on.

    https://github.com/espruino/Espruino/blob/fb99bda56518dfa50218fc419b24fac3584cfd9d/libs/network/esp32/network_esp32.c#L199-L203

    I have also observed this behaviour in the ESP8266 build.

  • Hmm, yeah - it seems like something that would be good to fix, since it is a nuisance during development to have to power cycle the board after each upload.

    I will try manually doing server.close()

    I am using the telnet connection - I think this is one of the most compelling features of the ESP8266/ESP32. It's so much more convenient than having to fiddle with wires to upload.

    For doing the time with the header, how do I access the headers from within Espruino? It doesn't appear to be supported (based on my reading of the reference) As I understand it, the callbacks provide an httpCRs and httpCRq object - but the API reference for these does not mention any method to get the headers.

  • I think httpCRq has a headers field on it?

  • >    require("http").get("http://drazzy.com/time.shtml", function(res) {
    console.log({GMT:res.headers.Date});
            var contents = "";
            res.on('data', function(data) { contents += data; });
            res.on('close', function() {
    console.log(contents);
    setTime(contents); });
     }).on('error', function(e) {
    :        console.log("ERROR", e);
    :    });
    =undefined
    {
      "GMT": "Wed, 13 Jun 2018 11:22:54 GMT"
     }
    Wed Jun 13 11:22:54 2018
    
  • Thanks.

    I've created an issue for the incomplete API documentation. https://github.com/espruino/EspruinoDocs/issues/441

  • @DrAzzy
    The initial problem you had should be largely sorted by this fix:

    https://github.com/espruino/Espruino/commit/5c9c7b5c561eda7408b2e5d8194f8127a6a5d5f6

    It allows the port to be reused.

  • I think I got this issue on an ESP32 with 2v01 when trying to use MQTT / tinyMQTT. reset(1), reset button, power cycling does not solve the problem. The board can connect to wifi, ping works.
    What really puzzles me is that I have an ESP32 with tinyMQTT that works.

    With MQTT the error message is ERROR: Connect failed (err 104)
    With tinyMQTT the error message is:

    ERROR: Connect failed (err 104)
    Uncaught InternalError: Unable to create socket
    

    at this call: a.cl=require("net").connect({host:a.svr,port:a.prt},b)

    Edit: A simple http get does work.
    Edit2: A simple http server works:

    function onPageRequest(req, res) {
      print('page req', req);
      res.writeHead(200);
      res.end("Ok.");
    }
    require("http").createServer(onPageRequest).listen(80);
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Unable to bind socket errors if ESP32 not powercycled between uploads, strange error messages

Posted by Avatar for DrAzzy @DrAzzy

Actions