ws-tool

An easy to use websocket client/server toolkit, supporting blocking/async IO.

feature matrix

| IO type | split | proxy(auth) | tls | buffered stream | deflate | use as client | use as server | | -------- | ----- | ----------- | --- | ---------------- | ------- | ------------- | ------------- | | blocking | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | async | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |

It's tested by autobaha test suit. see test report of 4 example

usage

Every example can be run with

bash cargo run --example <example_name> --all-features command.

See examples/server for building a websocket echo server with self signed certs.

run autobaha testsuit

start test server

bash ./script/start_autobahn_server.sh

run test on other terminal

bash cargo ac cargo aac cargo adc cargo aadc

report files should be under test_reports dir.

performance

Performance is a complex issue, and a single performance indicator is not enough to describe the performance of a certain library. Here we only compare QPS as a brief description of ws-tool performance

My test machine is i9-12900k and 32GB, 3200MHz ddr4, and load test client is load_test

Roughly compare with EchoSever example, tungstenite

The following are the benchmark(1 connection only) results

300 bytes payload size, 50000000 messages

rust cargo lt -- -p 300 --count 50000 -t 1 <url>

uWebSocket

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 10785 | 4636068.61 |

tungstenite

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 22045 | 2268088.00 |

blocking api(bench_server example) without buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 28473 | 1756049.59 |

blocking api(bench_server example) 8k buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 10791 | 4633490.87 |

async api(benchasyncserver) without buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 41068 | 1217492.94 |

async api(benchasyncserver) with 8k buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|----------|--------------|-------------| | 0 | 0 | 50000000 | 14892 | 3357507.39 |

1M bytes payload size, 100000 messages

rust cargo lt -- -p 1048576 --count 100 -t 1 <url>

uWebSocket

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 37545 | 2663.47 |

tungstenite

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 41413 | 2414.70 |

blocking api(bench_server example) without buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 32689 | 3059.13 |

blocking api(bench_server example) 4M buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 29949 | 3339.01 |

async api(benchasyncserver) without buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 38959 | 2566.80 |

async api(benchasyncserver) with 4M buffer

| connection | iteration | count | Duration(ms) | Message/sec | |------------|-----------|--------|--------------|-------------| | 0 | 0 | 100000 | 31378 | 3186.95 |

you can try more combinations with load_test tool

http header style

for multiple extension/protocol, ws-tool prefer to use multiple header with the same name, instead of "," separated value. but ws-tool still try to parse extension/protocol from "," separated header value.

REF