Vadim Tsushko
2015-12-05 17:56:17 UTC
One of mine primary usage case for dart is all sorts of scripting to help
in my everyday job - BI development with Qlik (as qlik.com) products.
My immediate task in that area is to migrate existing infrastructure
supporting a development of QlikView BI projects to Qlik Sense.
Qlik Sense is a new product and the main interface to communicate with it
is through WebSockets (Qlik specifically claim that any client capable to
communicate through WebSockets could use their Qlik Sense API)
I have some experience with Dart WebSockets before and was relatively
confident that in that area I should not find big troubles. But in fact I
could not connect to QlikSense services with dart:io WebSockets.
Initially, I could not find any reasons for that and tried all sorts of
solutions. Strange fact for me was that I could successfully connect to
QlikSense services from within dart web applications (using dart:html
WebSocket implementation)
That was not very helpful for me though as I have to create CLI utility,
not the Web interface.
So my temporary solution is to write tiny transparent nodejs WebSocket
proxy. From dart script I interact with that proxy, and that proxy in turn
interacts with Qlik Sense service. That works for me now on development
stage, but for deployment that would be great burden indeed.
So I spent some time with WireShark to find what is different in WebSocket
handshaking of nodejs (successful) and dart:io (unsuccessful)
communication. For now I'm almost totally sure that difference and reason
why dart:io WebSocket connections break with error is that dart:io header
keys are converts to lowercase.
Successful communication looks like:
GET /app/%3Ftransient%3D HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Host: 192.168.188.10
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: MTMtMTQ0OTMzNjYzNzY0NQ==
Content-Type: application/json
Cookie: X-Qlik-Session=70a54c5b-a08b-4665-a0d7-1a39871ebea9; Path=/;
HttpOnly; Secure
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: Tb5mxSaTiFApEyYAAv/ci7AMOzI=
Access-Control-Allow-Origin: ws://192.168.188.10
Unsuccessful communication looks like:
GET /app/%3Ftransient%3D HTTP/1.1
user-agent: Dart/1.14 (dart:io)
connection: Upgrade
cache-control: no-cache
accept-encoding: gzip
cookie: X-Qlik-Session=70a54c5b-a08b-4665-a0d7-1a39871ebea9; Path=/;
HttpOnly; Secure
content-length: 0
sec-websocket-version: 13
host: 192.168.188.10
sec-websocket-extensions: permessage-deflate; client_max_window_bits
content-type: application/json
sec-websocket-key: lVH5YxHL8QjS7ddjIJ/Ohg==
upgrade: websocket
HTTP/1.1 404 Not Found
Content-Length: 0
Access-Control-Allow-Origin: ws://192.168.188.10
I did not find any way to pass intact (not converted to lowercase) headers
to dart:io WebSocket or HttpClient. So finally I've tried raw Socket and
with it (writing to it capitalized Connection and Upgrade as header keys)
I've managed to get switching protocol response from the Qlik Sense
WebSocket server. So apparently from that I can proceed to create WebSocket
from manually upgraded WebSocket.
But I wonder now- is Qlik Sense WebSocket server implementation is wrong to
reject dart:io client WebSocket connections? Or dart:io WebSockets are
somehow not strictly adhere to specification?
Dart:io WebSocket client successfully connects to http://www.websocket.org/
sample server, to dart:io WebSocket servers, to nodejs ws server - but how
many `Qlik Sense like` not compatible with dart:io WebSocket servers are in
the wild?
Communication example on Wikipedia looks more like nodejs version (with
capitalized keys)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
in my everyday job - BI development with Qlik (as qlik.com) products.
My immediate task in that area is to migrate existing infrastructure
supporting a development of QlikView BI projects to Qlik Sense.
Qlik Sense is a new product and the main interface to communicate with it
is through WebSockets (Qlik specifically claim that any client capable to
communicate through WebSockets could use their Qlik Sense API)
I have some experience with Dart WebSockets before and was relatively
confident that in that area I should not find big troubles. But in fact I
could not connect to QlikSense services with dart:io WebSockets.
Initially, I could not find any reasons for that and tried all sorts of
solutions. Strange fact for me was that I could successfully connect to
QlikSense services from within dart web applications (using dart:html
WebSocket implementation)
That was not very helpful for me though as I have to create CLI utility,
not the Web interface.
So my temporary solution is to write tiny transparent nodejs WebSocket
proxy. From dart script I interact with that proxy, and that proxy in turn
interacts with Qlik Sense service. That works for me now on development
stage, but for deployment that would be great burden indeed.
So I spent some time with WireShark to find what is different in WebSocket
handshaking of nodejs (successful) and dart:io (unsuccessful)
communication. For now I'm almost totally sure that difference and reason
why dart:io WebSocket connections break with error is that dart:io header
keys are converts to lowercase.
Successful communication looks like:
GET /app/%3Ftransient%3D HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Host: 192.168.188.10
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: MTMtMTQ0OTMzNjYzNzY0NQ==
Content-Type: application/json
Cookie: X-Qlik-Session=70a54c5b-a08b-4665-a0d7-1a39871ebea9; Path=/;
HttpOnly; Secure
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: Tb5mxSaTiFApEyYAAv/ci7AMOzI=
Access-Control-Allow-Origin: ws://192.168.188.10
Unsuccessful communication looks like:
GET /app/%3Ftransient%3D HTTP/1.1
user-agent: Dart/1.14 (dart:io)
connection: Upgrade
cache-control: no-cache
accept-encoding: gzip
cookie: X-Qlik-Session=70a54c5b-a08b-4665-a0d7-1a39871ebea9; Path=/;
HttpOnly; Secure
content-length: 0
sec-websocket-version: 13
host: 192.168.188.10
sec-websocket-extensions: permessage-deflate; client_max_window_bits
content-type: application/json
sec-websocket-key: lVH5YxHL8QjS7ddjIJ/Ohg==
upgrade: websocket
HTTP/1.1 404 Not Found
Content-Length: 0
Access-Control-Allow-Origin: ws://192.168.188.10
I did not find any way to pass intact (not converted to lowercase) headers
to dart:io WebSocket or HttpClient. So finally I've tried raw Socket and
with it (writing to it capitalized Connection and Upgrade as header keys)
I've managed to get switching protocol response from the Qlik Sense
WebSocket server. So apparently from that I can proceed to create WebSocket
from manually upgraded WebSocket.
But I wonder now- is Qlik Sense WebSocket server implementation is wrong to
reject dart:io client WebSocket connections? Or dart:io WebSockets are
somehow not strictly adhere to specification?
Dart:io WebSocket client successfully connects to http://www.websocket.org/
sample server, to dart:io WebSocket servers, to nodejs ws server - but how
many `Qlik Sense like` not compatible with dart:io WebSocket servers are in
the wild?
Communication example on Wikipedia looks more like nodejs version (with
capitalized keys)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.