{"id":13578624,"url":"https://github.com/PrivateRookie/ws-tool","last_synced_at":"2025-04-05T19:33:21.505Z","repository":{"id":43012679,"uuid":"359692191","full_name":"PrivateRookie/ws-tool","owner":"PrivateRookie","description":"High perform \u0026 easy to use websocket client/server","archived":false,"fork":false,"pushed_at":"2024-01-11T06:45:35.000Z","size":3942,"stargazers_count":196,"open_issues_count":8,"forks_count":27,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-05T00:01:48.603Z","etag":null,"topics":["proxy","rust","websocket","websocket-server"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PrivateRookie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-20T05:15:29.000Z","updated_at":"2025-02-27T09:33:27.000Z","dependencies_parsed_at":"2024-01-11T09:13:47.494Z","dependency_job_id":null,"html_url":"https://github.com/PrivateRookie/ws-tool","commit_stats":{"total_commits":78,"total_committers":3,"mean_commits":26.0,"dds":"0.038461538461538436","last_synced_commit":"c9e7074ee78ac31038a738f9b75b82eda32560ae"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PrivateRookie%2Fws-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PrivateRookie%2Fws-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PrivateRookie%2Fws-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PrivateRookie%2Fws-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PrivateRookie","download_url":"https://codeload.github.com/PrivateRookie/ws-tool/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266562,"owners_count":20910836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["proxy","rust","websocket","websocket-server"],"created_at":"2024-08-01T15:01:32.324Z","updated_at":"2025-04-05T19:33:20.932Z","avatar_url":"https://github.com/PrivateRookie.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# ws-tool\n\nAn easy to use websocket client/server toolkit, supporting blocking/async IO.\n\n**feature matrix**\n\n| IO type  | split | proxy | tls | buffered  stream | deflate | use as client | use as server |\n| -------- | ----- | ----- | --- | ---------------- | ------- | ------------- | ------------- |\n| blocking | ✅     | ✅     | ✅   | ✅                | ✅       | ✅             | ✅             |\n| async    | ✅     | ✅     | ✅   | ✅                | ✅       | ✅             | ✅             |\n\nweb framework integration\n\n- **axum** see [examples/ext_axum](./examples/ext_axum.rs)\n- **poem** see [examples/ext_poem](./examples/ext_poem.rs)\n\nFor tls connection, ws-tool support both native-tls and rustls,\nws-tool also support simd utf checking for faster utf8 string checking.\n\nIt's tested by autobaha test suit. see [test report](https://privaterookie.github.io/ws-tool-stat/clients/index.html) of 4 example\n\n\n\n## usage\n\nEvery example can be run with\n\n```bash\ncargo run --example \u003cexample_name\u003e --all-features\n```\ncommand.\n\nSee \n- [examples/echo_async_server](examples/server.rs) for building a websocket echo server with self signed cert.\n- [examples/echo](examples/echo.rs) demonstrates how to connect to a server.\n- [binance](examples/binance.rs) demonstrates how to connect to wss server via http/socks proxy\n- [poem](examples/poem.rs) demonstrates how to integrate with poem web framework.\n- autobaha_xxx_client are autobaha test suit client\n- bench_xxx are benchmark server examples, showing how to control read/write buffer or other low level config\n\n\n### run autobahn testsuite\n\nstart test server\n\n```bash\n./script/start_autobahn_server.sh\n```\n\nrun test on other terminal\n\n```bash\ncargo ac\ncargo aac\ncargo adc\ncargo aadc\n```\n\nreport files should be under `test_reports` dir.\n\n**performance**\n\n\nPerformance 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\n\nMy test machine is i9-12900k and 32GB, 3200MHz ddr4, and load test client is [load_test](./examples/load_test.rs)\n\nRoughly compare with [EchoSever example](https://github.com/uNetworking/uWebSockets/blob/master/examples/EchoServer.cpp),  [tungstenite](./examples/bench_tungstenite.rs)\n\n\nThe following are the benchmark(1 connection only) results, there is no tungstenite with buffered stream test case, because there tungstenite does not work well with buffered stream, fastwebsockets is not added, because it's performance is very bad in this test case, if you know how to improve fastwebsockets performance, please open a PR! tokio runtime use current_thread flavor.\n\n\n### 300 bytes payload size, 100000000 messages\n\n```rust\ncargo lt -- -b 819200 -p 300 --count 100000 -t 1 \u003curl\u003e\n```\n\n| server                   | count     | Duration(ms) | Message/sec     |\n| ------------------------ | --------- | ------------ | --------------- |\n| uWebSocket               | 100000000 | 10014        | 9986019.57      |\n| tungstenite              | 100000000 | 21566        | 4636928.50      |\n| bench_server(8k)         | 100000000 | 29597        | 3378720.82      |\n| bench_server(800k)       | 100000000 | 9320         | **10729613.73** |\n| bench_async_server(8k)   | 100000000 | 17846        | 5603496.58      |\n| bench_async_server(800k) | 100000000 | 14006        | 7139797.23      |\n\n\n### 1M bytes payload size, 100000 messages\n\n```rust\ncargo lt -- -p 1048576 --count 100 -t 1 \u003curl\u003e\n```\n\n| server                        | count  | Duration(ms) | Message/sec |\n| ----------------------------- | ------ | ------------ | ----------- |\n| uWebSocket                    | 100000 | 34195        | 2924.40     |\n| tungstenite                   | 100000 | 40139        | 2491.34     |\n| bench_server(no buffer)       | 100000 | 16405        | **6095.70** |\n| bench_server(8k)              | 100000 | 17240        | 5800.46     |\n| bench_async_server(no buffer) | 100000 | 17190        | 5817.34     |\n| bench_async_server(8k)        | 100000 | 17027        | 5873.03     |\n\n\nyou can try more combinations with [load_test](./examples/load_test.rs) tool\n\n## http header style\n\nfor multiple extension/protocol, ws-tool prefer to use multiple header with the same name, instead of \",\" separated value.\nbut ws-tool still try to parse extension/protocol from \",\" separated header value.\n\n\n## REF\n\n- [WebSocket RFC](https://datatracker.ietf.org/doc/html/rfc6455)\n- [permessage-deflate RFC](https://datatracker.ietf.org/doc/html/rfc7692)\n- [tungstenite-rs](https://github.com/snapview/tungstenite-rs)\n- [ws-rs](https://github.com/housleyjk/ws-rs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPrivateRookie%2Fws-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPrivateRookie%2Fws-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPrivateRookie%2Fws-tool/lists"}