RSV1 set to one but must be zero
gitneko opened this issue · 3 comments
I'm currently in the works of making this library work with MKR1000 and WiFi101 and I'm testing this with a Node.js websocket client. However whenever I try to send a message from Node.js, the connection will fail with Invalid WebSocket frame: RSV1 must be clear
, which indicates this library sets RSV1
to one, even though no extension was actually negated (websockets/ws#1140 (comment), https://tools.ietf.org/html/rfc6455#section-5.2).
In my config.h I've uncommented the "debug macros"
#define _DEBUG
#define _DUMP_HANDSHAKE
#define _DUMP_HEADER
#define _DUMP_FRAME_DATA
And on the serial I can see the following getting printed (and that's all of it):
17:43:13.645 -> [Line #0] GET / HTTP/1.1
17:43:13.645 -> [Line #1] Sec-WebSocket-Version: 13
17:43:13.645 -> [Line #2] Sec-WebSocket-Key: aaab5frEyNghA1Yrsz9Fxg==
17:43:13.645 -> [Line #3] Connection: Upgrade
17:43:13.645 -> [Line #4] Upgrade: websocket
17:43:13.645 -> [Line #5] Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
17:43:13.645 -> [Line #6] Host: 192.168.1.39:3000
17:43:13.645 -> [Line #7]
17:43:13.679 -> New websocket connection
Node.js output:
connected
RangeError: Invalid WebSocket frame: RSV1 must be clear
at Receiver.getInfo (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:178:14)
at Receiver.startLoop (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:131:22)
at Receiver._write (C:\Users\GG\Downloads\node_modules\ws\lib\receiver.js:78:10)
at writeOrBuffer (_stream_writable.js:352:12)
at Receiver.Writable.write (_stream_writable.js:303:10)
at Socket.socketOnData (C:\Users\GG\Downloads\node_modules\ws\lib\websocket.js:872:35)
at Socket.emit (events.js:314:20)
at addChunk (_stream_readable.js:307:12)
at readableAddChunk (_stream_readable.js:282:9)
at Socket.Readable.push (_stream_readable.js:221:10) {
[Symbol(status-code)]: 1002
}
Node.js client code:
const WebSocket = require('ws');
const ws = new WebSocket('ws://192.168.1.39:3000');
const data = {
"type": "standard",
"id": 128,
"dlc": null,
"rtr": false,
"data": "hello123"
};
ws.on('error', function (error) {
console.log(error);
});
ws.on('open', function () {
console.log('connected');
setTimeout(() => ws.send(JSON.stringify(data)), 2000);
});
ws.on('message', function (data) {
console.log(data);
});
I'm using a little more code for all my setup and peripheries, but this is a simplified version:
net::WebSocketServer wss(3000);
void ws_configure_websocket() {
wss.onConnection([](net::WebSocket& ws) {
ws.onClose([](net::WebSocket& wsc, const net::WebSocket::CloseCode& code, const char* reason, uint16_t length) {
Serial.println("Websocket client closed");
});
ws.onMessage([](net::WebSocket& wsc, const net::WebSocket::DataType& dataType, const char* message, uint16_t length) {
Serial.println("New websocket message");
});
Serial.println("New websocket connection");
});
wss.begin();
}
void ws_loop_websocket() {
int status = WiFi.status();
if (status == WL_CONNECTED) {
wss.listen();
}
}
void setup() {
ws_configure_websocket();
}
void loop() {
ws_loop_websocket();
}
- Test against RSV passed
- This implementation does not support any websocket extensions (due to lack of memory).
Can you force disable permessage-deflate
in node.js?
The Node.js ws client documentation says that the extension is only enabled if the server supports it and it is enabled, which means that the extension must be negotiated before it is used (which is done by sending a HTTP header in the response to the initial HTTP request).
Which suggests to me, even though the server does not support it, it sends a RSV1 even though it's not enabled and negotiated. Looking at the code, the protocol implementation seems flawed to me. I'll report back after more investigation and testing.
On your server listing I don't see any RX FRAME
TX FRAME