Websocket serve bound to port 80

Posted on
  • I can't get this to work. Other ports work fine, but if I try bind the server to port 80, I get:-

    ERROR: Unable to create socket
    

    All the examples seem to use ports other than 80, so I wonder if I'm missing something?

  • Actually, it seems the board just needed resetting. Maybe already bound to another port - I don't know. Anyway it works.

    @Gordon please delete if deem appropriate.

  • No problem. Probably worth leaving up in case anyone has similar problems.

    Which board were you using, and was the Web IDE set up to send reset() when uploading (the default?).

    Stuff like Espruino WiFi and the Pico+WiFi should automatically reset the WiFi module each time code is uploaded. The ESP8266 itself wouldn't do that, although the socket server should automatically shut connections down on a software reset()

  • It's a NodeMCU. I think it may have been that I had a persistent wifi connection with wifi.save() at the time. Anyway I've stripped that out so wifi connection is established at code send, but I'm still having issues - not related to ports but with the websocket module in general.

    I worked it into my code last night and found it would not work in Chrome. In Firefox, the server can send, but the client cannot send back - or at least the message is never received.

    I've stripped my code back to basically just run the server example on the websockets page and still no joy.

    In chrome, nothing from the server and I get this in console.

    WebSocket connection to 'ws://192.168.1.16:8000/my_websocket' failed: A server must not mask any frames that it sends to the client.
    

    And an attempt to send with ws.send("...") gets this in response:-

    WebSocket is already in CLOSING or CLOSED state.
    

    In Firefox I get the server sent message MSG:Hello from Espruino!
    But nothing back from the client. Also trying ws.send("...") from console also does not get received.

    The connection appears to get upgraded based on my logging, but the ws.on('message', function(){...}) event handler never fires.

    This is the code, almost identical to the example

    var wifi = require("Wifi");
    var ap2 = {
      "ssid": "xxxx",
      "pwd": "xxxx"
    };
    // Wifi connection
    wifi.connect(ap2.ssid, {"password": ap2.pwd}, function(err){
      if(!err){
        console.log("Connected to Wifi");
        var page = '<html><body><script>var ws;setTimeout(function(){';
        page += 'ws = new WebSocket("ws://" + location.host + "/my_websocket", "protocolOne");';
        page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };';
        page += 'setTimeout(function() { ws.send("Hello to Espruino!"); }, 2000);';
        page += '},2000);</script></body></html>';
    
        var onPageRequest = function(req, res) {
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end(page);
        };
    
        var server = require('ws').createServer(onPageRequest­);
        server.listen(8000);
        server.on("websocket", function(ws) {
          console.log("Connection upgraded");
          ws.on('message',function(msg) {
            console.log("Message received");
            print("[WS] "+JSON.stringify(msg));
          });
          ws.send("Hello from Espruino!");
        });
     }
    });
    

    Could there be a problem with the module? I'm struggling to see how I could be going wrong?

  • Try now... It looks like it was an issue with the module.

    As far as I can tell, the browsers keep tweaking their implementations, and things that used to work don't. I'm pretty sure the server was tested at some point quite recently.

  • That's fixed it! Have messaging both ways in Chrome. Excellent thank you @Gordon!

  • One further issue, maybe a showstopper. I'm now testing on mobile Safari and Google Chrome - both based on Webkit - and I get this in Mobile Safari (I'm not able to debug in Chrome but infer same)

    WebSocket connection to 'ws://192.168.1.17:8000/espruinocar' failed: Invalid HTTP version string: HTTP/1.0
    

    Looking into this, I'm not sure that HTTP/1.0 websockets are supported any longer. I seem to recall reading that Espruino HTTP/Websockets is still on the 1.0 standard. Is this correct?

    I am guessing I'd fare better in Android :/

  • Yeah, that's built into Espruino.

    As a hack you could get a hex editor, search the binary file for HTTP/1.0 and change it to something else (of course then it might be that Safari tries to do something that Espruino can't)

  • Well that's worth a shot. Thanks again.

  • If I may, Gordon you're a genius. That was enough to bamboozle Safari! I've got data and the connection seems just as stable as desktop.

  • \o/ what did you change it to? It's possible that 1.1 might not cause too many problems for other things... Or we could make it configurable.

  • Just 1.1. And it has been fine. We brought the whole rc car project together tonight (thankfully) and have been driving it from iPhone - needs a couple of tweeks - but nothing major.

    Thanks for your help on the websockets piece today.

  • Hi,

    I'm getting the same problem in that Safari doesn't like the HTTP/1.0 header form the Espruino.

    WebSocket connection to 'ws://192.168.1.111' failed: Invalid HTTP version string: HTTP/1.0
    

    Can you explain a little more about how to fix it?

    Sean

  • @Ollie did you ever notice any problems using 1.1 as the version string - eg when trying to serve up normal webpages?

    @seanclark this actually required changing the binary manually - so it's not an easy option. YOu basically download the build, open it with a hex editor then search for HTTP/1.0 and change it to HTTP/1.1. Ideally I'd change it in the builds themselves though, but I'm a little worried it may cause other problems.

  • @Gordon No, I've had no issues, but admittedly this binary only serves a RC car controller webpage and the websocket connection. I'm not using it anywhere else, but it works like a charm for that. Maybe not enough evidence to change it :)

  • Just changed it in GitHub so the latest builds will have the change - I'll see what happens when it gets some use. I can't imagine hitting many problems.

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

Websocket serve bound to port 80

Posted by Avatar for Ollie @Ollie

Actions