Websocket's listeners are ingored?

Posted on
  • I'm facing a strange situation: after changing the code, the event listeners are not registered anymore.

    The code now looks like:

    MyClass.prototype.initialize = function () {
        var self = this;
        self.wifi.connect( self.ssid, { password:self.wlanPw }, function( err ){
          console.log( "connected? info=", self.wifi.getIP() );
          if( !err ) self.connect();
        } );
    }
    
    MyClass.prototype.connect = function () {
    	this.ws = new WS( this.serverHost, { port:8822 } );
    	this.ws.gwId = this.wifi.getIP().mac;
    	this.ws.premiseId = this.premiseId;
    	this.ws.handshake = this.handshake.bind( this.ws );
    	this.ws.on( 'open', function(){
    	  console.log( 'ws openned' );
    	} );
    	this.ws.on( 'message', this.onWsMessage );
    	this.ws.on( 'close', this.onWsClose );
    
    	console.log( "Connecting to ", this.serverHost, 8822 );
    };
    
    MyClass.prototype.onWsMessage = function( msg ) { doSomething(); };
    MyClass.prototype.onWsClose = function() { ... };
    

    in the console I see

    connected? info= {
    "ip": "192.168.0.16",
    "netmask": "255.255.255.0",
    "gw": "192.168.0.1",
    "mac": "5c:cf:7f:19:71:73"
    }
    Connecting to ec2-52-34-212-117.us-west-2.compute.amazonaws.com 8822

    I see also, that the WS request hits the server.

    It used to work, so now I'm banging my head trying to figure out what could possibly go wrong here...

  • ...how was it - the code - looking before?

  • Which board/firmware are you using? It would probably help to have the complete bit of code too.

  • Ok, I nailed the problem. My code doesn't work with the latest remote version of ws module -> http://www.espruino.com/modules/ws.js.

    Luckily I have a local (slightly modified) version of the ws-module (without the crypto module), and with this one the code from above works as before!

    Gordon, can you please modify the following lines in the ws module?

    function WebSocket(host, options) {
      this.socket = null;
      options = options || {};
      this.host = host;
      this.port = options.port || 80;
      this.protocolVersion = options.protocolVersion || 13;
      this.origin = options.origin || 'Espruino';
      this.keepAlive = options.keepAlive * 1000 || 60000;
      this.masking = options.masking!==undefined ? options.masking : true;
      this.path = options.path || "/";
      this.protocol = options.protocol;
      this.lastData = "";
      this.key = buildKey();
      this.connected = false || options.connected;
      this.headers = options.headers || {};
    }
    
    WebSocket.prototype.handshake = function () {
      var socketHeader = [
        "GET " + this.path + " HTTP/1.1",
        "Host: " + this.host,
        "Upgrade: websocket",
        "Connection: Upgrade",
        "Sec-WebSocket-Key: " + this.key.source,
        "Sec-WebSocket-Version: " + this.protocolVersion,
        "Origin: " + this.origin
      ];
      if (this.protocol)
        socketHeader.push("Sec-WebSocket-Protocol: "+this.protocol);
      
      for( var key in this.headers ){
        if( this.headers.hasOwnProperty( key ) )
          socketHeader.push( key + ": " + this.headers[ key ] );
      }
    
      this.socket.write(socketHeader.join("\r\n")+"\r\n\r\n");
    };
    

    so that I can further test my stuff the new ws code

  • Can you just try it using require("https://raw.githubusercontent.com/espruino/EspruinoDocs/master/modules/ws.js") - maybe with your own GitHub?

    I'd rather not stick that code in just so you can test, especially as it's a bit confusing (eg, if you can stick your own headers in there, they just get ignored).

    I'm guessing you're using in ESP8266 then? I'm kind of surprised it didn't give you an error when it tried to build the key? As far as I can tell, nothing stops you from just doing:

    this.ws = new WS( this.serverHost, { port:8822 } );
    this.ws.key = {
      source : "...", 
      hashed :  "..."
    };
    
  • @Gordon The code is not about "my testing" :), it provides a possibility to inject optional headers (like auth) into the Websocket's handshake - lines 31-34.

    As of now this is possible only if you override the default handshake() method, but as my case shows, it might break some things up (like crypto key gets lost).

    I'm using ESP8266 indeed, and the handshake code I provided works just fine with crypto and optional request headers.

  • So you were using the WebSocket module, but you'd overridden WebSocket.prototype.handshake with an older version in a section of code that you didn't post up, and that's what broke it?

    Was there a problem with using the module as-is, assuming you don't want the custom headers?

    Memory is scarce on ESP8266 as is, and I've already had complaints about Websockets and MQTT libraries taking up too much space.

    Basically I'm stuck in the middle. I get people complaining whatever change I make - but there's no point me annoying other users by making a change that's not documented, that a fraction of a percent of Espruino users will ever discover.

    If you want to give me a pull request with it in, and with the relevant documentation in the ws.md file so people actually know it exists and how to use it, that'd be cool - but I don't have time to do it I'm afraid.

  • Yep, I had a modified copy of old handshake() code with hard-coded Sec-WebSocket-Key instead of new this.key.source. The result was, that no open event was emitted. After I poured the new crypto-aware code in, the problem disappeared.

    I created a pull-request. Please see https://github.com/espruino/EspruinoDocs/pull/289. It shouldn't have any impact on space requirement for the library.

  • Thanks - I'll update the website with the new version this week.

    It will push the space requirement up a bit (maybe 5-10 vars extra?) just because there's more code and an extra variable, but hopefully that won't be too big a deal for others

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

Websocket's listeners are ingored?

Posted by Avatar for Injecteer @Injecteer

Actions