Websocket Proxy
All the application code here is available from the docs git repository.
Example Websocket proxy application built on top of Tremor and meant to be a demonstration of linked transports.
Setup
All the code here is available in the git repository as well.
Sources and sinks
We configure a websocket onramp listening on port 9139, that is meant to be a proxy for our example websocket server (configured as en endpoint in the websocket offramp here).
onramp:
- id: ws
type: ws
linked: true
codec: string
preprocessors:
- lines
config:
host: 0.0.0.0
port: 9139
offramp:
- id: upstream
type: ws
linked: true
codec: string
postprocessors:
- lines
config:
url: "ws://tremor-server:8139"
Message flow
Incoming websocket messages from a client's websocket connection are forwarded to the upstream websocket server (via the pass_incoming
pipeline which lives up to its name). The resulting upstream reply is then returned back to the client reusing its connection (after a quick pass through the pass_outgoing
pipeline).
binding:
- id: main
links:
"/onramp/ws/{instance}/out":
["/pipeline/pass_incoming/{instance}/in"]
"/pipeline/pass_incoming/{instance}/out":
["/offramp/upstream/{instance}/in"]
"/offramp/upstream/{instance}/out":
["/pipeline/pass_outgoing/{instance}/in"]
"/pipeline/pass_outgoing/{instance}/out":
["/onramp/ws/{instance}/in"]
Processing logic
Implementation for the pass_incoming
(as well as pass_outgoing
) pipeline:
select event from in into out;
This example is intentionally light on the processing but you can imagine doing arbitrary processing based on the event data here (as well as dynamically changing the confiuration for the websocket offramp via its metadata variables -- eg: things like the server url).
Testing
Assuming you have all the code from the git repository, run the following to start our application (along with the tremor websocket server example that is the upstream for our proxy):
docker-compose up
Now let's try to test the echo capabilities of our upstream server, via a tool like websocat.
Can be installed via cargo install websocat
for the lazy/impatient amongst us
# via proxy
$ echo "hello" | websocat -n1 ws://localhost:9139
hello
# the upstream
$ echo "hello" | websocat -n1 ws://localhost:8139
hello
Our snot-handling works as well:
$ echo "snot" | websocat -n1 ws://localhost:9139
badger
And if there's an internal tremor error while processing both the incoming message and the upstream reply to it (eg: codec or pre/post-processor failure), or if the upstream server is down, an error will be bubbled up to the client. Example:
# stop the upstream server
$ docker stop 33_proxies_lt_ws_tremor-server_1
# upstream connection now gets closed from the proxy
$ echo "hello" | websocat -n1 ws://localhost:9139
{"error":"Error receiving reply from server ws://localhost:8139: WebSocket protocol error: Connection reset without closing handshake","event_id":"
1:0:9"}
# sending further messages results in errors
$ echo "hello" | websocat -n1 ws://localhost:9139
$ echo "hello" | websocat -n1 ws://localhost:9139
{"error":"Error sending event to server ws://localhost:8139: Trying to work with closed connection","event_id":"1:0:10"}