2019-02-13

Turn any program that uses STDIN/STDOUT into a WebSocket server using websocketd

Yesterday I tried for the first time websocketd and it is amazing!
This is a little gem created by @joewalnes that let you implement language agnostic WebSocket applications based on any command line program reading text from stdin and writing a message output to stdout. A simple (and genial) approach.

If think that it is perfect for testing too, so I updated an existing integration test for a WebSocket client  of mine using a local websocketd server on TravisCI instead of relying on external public services requiring internet as done before (wss://echo.websocket.org). This activity was already on my roadmap so why not try out websocketd?!

As you can see here (https://github.com/davidemoro/pytest-play-docker/pull/42/files): in .travis.yml I added a before_script calling a travis/setup_websocket.sh script that installs and runs websocketd in background on port 8081 based on a simple travis/echo_ws.sh that reads a line from stdin echoing to stdout.

The websocketd syntax is the following:

./websocketd --port=8081 ./echo_ws.sh

were echo_ws.sh can be any executable stdin/stdout based. More details in next section.

Wanna tryout websocketd?

Download a websocketd version compatible with your OS/architecture and unzip the folder from http://websocketd.com/#download: it contains a websocketd executable ready to be used so no installation needed and follow the tutorials described in https://github.com/joewalnes/websocketd/wiki.

Alternatively you can test websocketd using pytest-play's play_websocket plugin that is ready to be used assuming that you have Docker installed.
docker run --rm -it -v $(pwd):/src --network host davidemoro/pytest-play --variables variables.yml
Additional links you might find useful for this example:
#!/bin/bash
while read line
do
echo "$line"
done
view raw echo_ws.sh hosted with ❤ by GitHub
$ docker run --rm -it -v $(pwd):/src --network host davidemoro/pytest-play --variables variables.yml
========================================================= test session starts =========================================================
platform linux -- Python 3.6.8, pytest-3.10.1, py-1.7.0, pluggy-0.8.1
rootdir: /src, inifile:
plugins: variables-1.7.1, splinter-2.0.0, pypom-navigation-2.0.2, play-2.0.1
collected 2 items
test_websocket.yml .. [100%]
========================================================== warnings summary ===========================================================
test_websocket.yml::test_websocket.yml0
/usr/local/lib/python3.6/site-packages/_pytest/fixtures.py:828: RemovedInPytest4Warning: Fixture "tmpdir" called directly. Fixtures are not meant to be called directly, are created automatically when test functions request them as parameters. See https://docs.pytest.org/en/latest/fixture.html for more information.
res = fixturefunc(**kwargs)
-- Docs: https://docs.pytest.org/en/latest/warnings.html
================================================ 2 passed, 1 warnings in 2.38 seconds =================================================
view raw output hosted with ❤ by GitHub
#!/bin/bash
docker run --rm -it -v $(pwd):/src --network host davidemoro/pytest-play --variables variables.yml
view raw run.sh hosted with ❤ by GitHub
#!/bin/bash
./websocketd --port=8081 ./echo_ws.sh
test_data:
- data: hello
- data: world
---
- comment: connect to websocket url
provider: play_websocket
type: connect
options:
url: "$websocket_url"
timeout: 5
- comment: send some data to websocket server
provider: play_websocket
type: send
url: "$websocket_url"
payload: $data
- comment: receive response (echo)
provider: play_websocket
type: recv
url: "$websocket_url"
variable: data
variable_expression: results
assertion: variables['data'] == '$data'
---
pytest-play:
websocket_url: ws://0.0.0.0:8081/
view raw variables.yml hosted with ❤ by GitHub

No comments:

Post a Comment

Note: only a member of this blog may post a comment.