-
If I try connecting to wss://myserver.com:8822:
var ws = require( 'ws' )( 'beta.mozaiq.io', { port:8822 } )
I get
console.log( ws.lastData )
HTTP/1.1 400 Bad Request
Server: nginx/1.10.1
Date: Mon, 13 Feb 2017 11:35:49 GMT
Content-Type: text/html
Content-Length: 271
Connection: close
400 The plain HTTP request was sent to HTTPS portIn the chrome ws-client the connection over wss:// is working.
I have another SSL-free ws-endpoint on 8827 on my server, and it's working just fine in ESP.
-
-
Yep, I had a modified copy of old
handshake()
code with hard-codedSec-WebSocket-Key
instead of newthis.key.source
. The result was, that noopen
event was emitted. After I poured the newcrypto
-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.
-
@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.
-
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
-
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 8822I 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...
-
-
-
So, after peeking the websocket code, I figured out what I did wrong. The correct code would be:
require("net").connect( { host:host, port:8823 }, function ( socket ) { socket.end( JSON.stringify( obj ) ); } );
The trick was to use the
socket
as a callback-function's argument, instead of theconnect()
result.
The documentation should be updated I guess, as this line is totally misguiding -
-
@ClearMemory041063 thanks for the code!
Connecting 2 esp's is not my use-case. I rather need to establish a connection to a plain java (Server)Socket. My ESP JS code is very similar to yours. The code snippet I posted is executed in
wifi.connect()
's callback-function and it's wifi-ing successfully. The rest is almost 1 to 1. -
@Kolban thanks for the answer!
Previously I had
socket.on( 'close', .. )
and it was not invoked.I inserted
require("ESP8266").logDebug(true);
but no additional console output appeared...I can't really use
ping
, as the server doesn't provide any ICMP ports and so the code:require("ESP8266").ping( '192.168.0.113', function( p ){ console.log( 'ping', p ); } );
prints out:
=undefined
ping { "totalCount": 0, "totalBytes": 0, "totalTime": 0, "respTime": 0,
"seqNo": 0, "timeoutCount": 0, "bytes": 0, "error": -1 } -
I have the following code snippet:
var options = { host:"192.168.0.113", port:8823 }; var socket = require("net").connect( options, function() { socket.on('data', function(data) { console.log("HTTP> "+data); } ); } ); socket.end( JSON.stringify( obj ) ); console.log( 'should be sent by now' );
Upon running, the server does not receive any data.
I tried also socket.write( JSON.stringify( obj ) ) and putting write/end calls inside of the callback function - neither worked.
The test code in Groovy works just fine:
Socket s = new Socket() s.connect( new InetSocketAddress( "192.168.0.113", 8823 ) ) s.outputStream.withWriter{ it << 'aaaaa' }
-
-
I tried to follow the Example , but in Espruino IDE it didn't really work.
I tried the following:
module moq_base.js
var wifi = require( "Wifi" ); function MoqBase(){}; MoqBase.prototype.ssid; MoqBase.prototype.startPairing = function () {...}
and then "inherit":
var MoqBase = require( "moq_base" ); Moq.prototype = new MoqBase(); Moq.prototype.constructor = Moq; function Moq( options ) {....}
but it resulted in exceptions like
Uncaught Error: Constructor should be a function, but is Object
at line 5 col 21
Moq.prototype = new MoqBase();I tried also to define a plain function inside the "base" module and then call it, but it also fails - function not found.
So, are there any examples / tutorials on using JS-inheritance / inlcusion for ESP?
Or, it shouldn't be used and copy & paste is my only true friend?Thanks!
-
-
-
I'm using vertx.io. It seems to have masking on by default. here a discussion on masking
btw, would the
ws
module work over thewss
protocol? -
The connection is established and remains open now, whoohoo!
Although some other problems arose...
If I call e.g.
ws.send( JSON.stringify( { "type":'discoveryResponse', "data":[] } ) );
, then the connection gets closed, and the server logs the following:14:47:53.714 [vert.x-eventloop-thread-0] INFO com.my.GatewayWSVerticle - registered WS for [11.111.111.111] 14:48:26.090 [vert.x-eventloop-thread-0] ERROR i.vertx.core.net.impl.ConnectionBase - io.netty.handler.codec.CorruptedFrameException: unmasked client to server frame 14:48:26.090 [vert.x-eventloop-thread-0] INFO com.my.GatewayWSVerticle - unregistered WS for [11.111.111.111]
If I call
ws.initializeConnection();
then I get to see the following in the logs:14:50:14.331 [vert.x-eventloop-thread-0] ERROR i.vertx.core.net.impl.ConnectionBase - io.netty.handler.codec.CorruptedFrameException: unmasked client to server frame 14:50:14.331 [vert.x-eventloop-thread-0] ERROR i.vertx.core.net.impl.ConnectionBase - io.netty.handler.codec.DecoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0
-
Thanks for your reply Gordon!
I'm on esp8266.
I called
ws.initializeConnection();
in the left console, after I sent the code to device. It brought me the following console out:RAW: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Handshake Success Connection closed
so, the
ws
is in closed state immediately after initializing, and callingsend()
on a dead socket brings obviously nothing -
Using the following code in Espruino Web IDE:
var WebSocket = require("ws"); var ws = new WebSocket( 'mydomain.com', { port:8822 } ); ws.on('open', function() { console.log("Connected to server"); }); ws.on('message', function(msg) { console.log("MSG: " + msg); }); ws.on('close', function() { console.log("Connection closed"); }); ws.on('handshake', function() { console.log("Handshake Success"); }); ws.on('rawData', function(msg) { console.log("RAW: " + msg); }); ws.send( JSON.stringify( { text:'HHHHLLLLL' } ) );
I can see in the server logs, that the WS-connection is established and then closes within some milisecs:
12:24:06.009 [vert.x-eventloop-thread-0] INFO com.my.GatewayWSVerticle - registered WS for [11.111.111.111] 12:24:06.220 [vert.x-eventloop-thread-0] INFO com.my.GatewayWSVerticle - unregistered WS for [11.111.111.111]
If I enter ws.initializeConnection(); in the left-hand side of IDE, I'm getting the lines:
RAW: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Handshake Success Connection closed
If I connect to the very same server from my browser or from a z-way server @ raspi, then it works like charm.
Am I missing something or is it a WS-bug?
TIA
I have a NodeMCU dev board with ESP8266 MOD (?) chip on it. Is it compatible with EspruinoWIFI?