Open benbromhead opened 1 year ago
WebSocket frames are as follows. In the handshake the client can specify a sub-protocol to use (eg. "cql"
, "redis"
) and if the server supports it will include it in it's response header
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
Data frames can be sent with just binary in the payload, the client can send the inner protocol frames encoded this way.
libraries:
tokio-tungstenite::WebSocketStream
does not implement tokio::io::AsyncRead
/tokio::io::AsyncWrite
so it cannot be dropped in place of tokio::net::TcpStream
:
let ws_stream = accept_ws_connection(stream).await;
let (rx, tx) = tokio::io::split(ws_stream);
spawn_read_write_tasks(
self.codec.clone(),
rx,
tx,
in_tx,
out_rx,
out_tx.clone(),
terminate_rx,
);
Will probably need to modify parts of tungstenite-rs
/tokio-tungstenite
to implement AsyncRead
/AsyncWrite
. There is also the note that we only want the binary part of the message from the WebSocket frame payload. Ideally we would have a wrapper around parts of the tungstenite
code that pulls out the inner protocol binary so we can feed it straight into the Shotover codecs.
Scylla developed a small MVP in Typescript for using CQL over WebSockets: https://github.com/dfilimonow/CQL-Driver
This is a bit premature given the work that needs to be done to tungstenite
to get WebSocket support into Shotover but the simplest way to do this would be to add a field to the source config to enable WebSockets and disable standard TCP connections, rather than listen on different ports for standard TCP and WebSocket connections.
Is your feature request related to a problem? Please describe.
Code running in a WASM / Browser context generally doesn't have access to tcp sockets and the only networking available to them is via web sockets
Describe the solution you'd like
Supporting C*, Redis and Kafka protocols over web socket
Issues
This will need some support from the drivers in the js / ts / wasm community. We might need to show examples of how to use those drivers over websockets / or submit PRs