Pico and WiFi unable to create socket

Posted on
  • Hello all,

    Firstly, I have searched the error message I'm getting and haven't been able to apply it to my case, so here goes...

    I have built a little OLED Bitcoin price display thing and am connecting to cryptonator (via mrtimcakes https to http proxy) to get some prices. It all runs fine but after a few minutes I get the repeated error Uncaught InternalError: Unable to create socket.

    I poll the api once every 30 seconds and call a function to deal with the data. From what I understand this is a memory problem, but I'm at a loss as to how to progress. Code is here https://gist.github.com/gomako/bdac39e96­16709aa952ac04d0d5de019 and looks a bit like dog vomit, so excuse me for that!

  • Thanks for posting up the code, it's a nice idea! - I just gave it a try.

    What I believe is happening is Unable to create socket happens because you have too many active connections. Espruino via ESP8266 can handle around 4 I believe - but you fire off 3 at the same time.

    While that works normally, if a connection gets slowed down for some reason and isn't closed after 30 seconds, now you're using 4 at once. One more and it'll fail.

    If it's like me, I found that after a while it did start working again?

    function getPrices() {
      symbols.forEach(symbol => {
        let url = `${proxy}${api}${symbol}-${currency}`;
        console.log("Opening socket");
        h.get(url, function(res) {      
          let pricesRaw = "";
          res.on('data', function(d) { pricesRaw += d; });
          res.on('close', () => {
            console.log("Socket closed");
            prices[symbol] = JSON.parse(pricesRaw);
          });
        });
      });
      showPrices();
    }
    

    If you output when a socket opens and when it closes (like above), you'll probably be able to see it happening.

    So... Personally I'd request each of your symbols in turn, after each one has completed - that'll probably make these slightly broken connections far less frequent. You could actually update more often, but could just update each token in turn?

    You could also skip an update if something is already in progress (I believe connections will time out after 60 seconds anyway)

  • Just to add that there is something iffy going on with sockets getting into an invalid state, and that looks like a bug in the ESP8266 interface library for Espruino.

    However, I think that's likely caused by trying to run the 3 sockets concurrently.

    If you try this:

    function getPrices() {
      symbolCtr = symbolCtr+1;
      if (symbolCtr>=symbols.length) symbolCtr=0;
      let symbol = symbols[symbolCtr];
      let url = `${proxy}${api}${symbol}-${currency}`;
      console.log("Opening socket");
      h.get(url, function(res) {      
        let pricesRaw = "";
        res.on('data', function(d) { pricesRaw += d; });
        res.on('close', () => {
          console.log("Socket closed");
          prices[symbol] = JSON.parse(pricesRaw);
          showPrices();
        });
      }); 
    }
    

    every 10 seconds then I bet it'll be a lot more stable.

  • Ah fantastic! Thank you for replying. I wondered if it might be something to do with the forEach loop. It did start working again at random points. I'll try that out and let you know how it goes.

  • Maybe it is a timing issue and using a Promise could help.. dont know the complete code but something like this could work:

    function getPrices() {
      return new Promise((resolve, reject) => {
        h.get(`${proxy}${api}${symbols[++symbolC­tr % (symbols.length + 1)]}-${currency}`, res => {
          let pricesRaw = "";
          res.on('data', d => pricesRaw += d);
          res.on('close', () => (prices[symbol] = JSON.parse(pricesRaw), true) && resolve());
        });
      });
    }
    

    And in your other code just do:

    getPrices().then(showPrices);
    

    Error handling ommited for keeping it simple.. but you should take care of it :)

  • Ah nice, yes that would be good. I was thinking of putting a little script on my server to handle the api lookups and return all the data in one go so I wouldn't have to do the https -> http proxy either.

    I've not really done anything with promises but it looks like a good place to start

    Error handling ommited for keeping it simple.. but you should take care of it :)

    Of course! ;-)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Pico and WiFi unable to create socket

Posted by Avatar for gomako @gomako

Actions