{"id":18473432,"url":"https://github.com/swimos/ratchet","last_synced_at":"2025-04-04T22:05:18.467Z","repository":{"id":43482615,"uuid":"431082626","full_name":"swimos/ratchet","owner":"swimos","description":"Ratchet is a fast, robust, lightweight and fully asynchronous implementation of RFC6455 (The WebSocket protocol).","archived":false,"fork":false,"pushed_at":"2024-11-06T16:16:05.000Z","size":649,"stargazers_count":41,"open_issues_count":4,"forks_count":9,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-12-19T09:16:14.285Z","etag":null,"topics":["async","deflate","rust","tokio","websockets"],"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/swimos.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-11-23T11:58:02.000Z","updated_at":"2024-12-13T15:31:57.000Z","dependencies_parsed_at":"2024-12-27T19:13:15.746Z","dependency_job_id":"3aacc3e1-9cc5-4ba1-a52b-b9efee904c3d","html_url":"https://github.com/swimos/ratchet","commit_stats":{"total_commits":215,"total_committers":1,"mean_commits":215.0,"dds":0.0,"last_synced_commit":"04f67ebd1409254b492c8368119fdbc70c264ad8"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimos%2Fratchet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimos%2Fratchet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimos%2Fratchet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimos%2Fratchet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swimos","download_url":"https://codeload.github.com/swimos/ratchet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256110,"owners_count":20909240,"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":["async","deflate","rust","tokio","websockets"],"created_at":"2024-11-06T10:24:56.183Z","updated_at":"2025-04-04T22:05:18.446Z","avatar_url":"https://github.com/swimos.png","language":"Rust","funding_links":[],"categories":["Tools per Language"],"sub_categories":["Rust"],"readme":"\u003ca href=\"https://www.swimos.org\"\u003e\u003cimg src=\"https://docs.swimos.org/readme/marlin-blue.svg\" align=\"left\"\u003e\u003c/a\u003e\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n# Ratchet\n\nRatchet is a fast, robust, lightweight and fully asynchronous implementation\nof [RFC6455](https://datatracker.ietf.org/doc/html/rfc6455) (The WebSocket protocol). Complete with an optional\nimplementation of [RFC7692](https://datatracker.ietf.org/doc/html/rfc7692) (Compression Extensions For WebSocket).\n\nRatchet powers [SwimOS on Rust](https://github.com/swimos/swim-rust/); a framework for real-time streaming data\napplications.\n\n[![Crates.io][crates-badge]][crates-url]\n\n[crates-badge]: https://img.shields.io/crates/v/ratchet_rs.svg\n\n[crates-url]: https://crates.io/crates/ratchet_rs\n\n[Documentation](https://docs.rs/ratchet_rs/latest/ratchet_rs/)\n\n# Features\n\n- Implement your own extensions using [ratchet_ext](/ratchet_ext).\n- Per-message deflate with [ratchet_deflate](/ratchet_deflate) or enable with the `deflate`\n  feature.\n- Split WebSocket with the `split` feature.\n\n# Testing\n\nRatchet is fully tested and passes every Autobahn test for both client and server modes.\n\n# Examples\n\n## Client\n\n```rust\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Error\u003e {\n  let stream = TcpStream::connect(\"127.0.0.1:9001\").await?;\n  \n  let upgraded = subscribe(\n    WebSocketConfig::default(),\n    stream,\n    \"ws://127.0.0.1/hello\".try_into_request()?,\n  )\n  .await?;\n\n  let UpgradedClient { socket, subprotocol } = upgraded;\n  let mut buf = BytesMut::new();\n\n  loop {\n    match websocket.read(\u0026mut buf).await? {\n      Message::Text =\u003e {\n        websocket.write(\u0026mut buf, PayloadType::Text).await?;\n        buf.clear();\n      }\n      Message::Binary =\u003e {\n        websocket.write(\u0026mut buf, PayloadType::Binary).await?;\n        buf.clear();\n      }\n      Message::Ping | Message::Pong =\u003e {\n        // Ping messages are transparently handled by Ratchet\n      }\n      Message::Close(_) =\u003e break Ok(()),\n    }\n  }\n}\n```\n\n## Server\n\n```rust\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Error\u003e {\n    let listener = TcpListener::bind(\"127.0.0.1:9001\").await?;\n    let mut incoming = TcpListenerStream::new(listener);\n\n    while let Some(socket) = incoming.next().await {\n        let socket = socket?;\n\n        // An upgrader contains information about what the peer has requested.\n        let mut upgrader = ratchet::accept_with(\n            socket,\n            WebSocketConfig::default(),\n            NoExtProvider,\n            SubprotocolRegistry::default(),\n        )\n        .await?;\n\n        // You could opt to reject the connection\n        // upgrader.reject(WebSocketResponse::new(404)?).await?;\n        // continue;\n      \n        // Or you could reject the connection with headers\n        // upgrader.reject(WebSocketResponse::with_headers(404, headers)?).await;\n        // continue;\n\n        let UpgradedServer {\n            request,\n            mut websocket,\n            subprotocol,\n        } = upgrader.upgrade().await?;\n        \n        let mut buf = BytesMut::new();\n\n        loop {\n            match websocket.read(\u0026mut buf).await? {\n                Message::Text =\u003e {\n                    websocket.write(\u0026mut buf, PayloadType::Text).await?;\n                    buf.clear();\n                }\n                Message::Binary =\u003e {\n                    websocket.write(\u0026mut buf, PayloadType::Binary).await?;\n                    buf.clear();\n                }\n                Message::Ping | Message::Pong =\u003e {\n                  // Ping messages are transparently handled by Ratchet\n                }\n                Message::Close(_) =\u003e break,\n            }\n        }\n    }\n    \n    Ok(())\n}\n```\n\n## Deflate\n\n```rust\n  let mut websocket = ratchet::accept_with(\n      socket,\n      WebSocketConfig::default(),\n      DeflateProvider,\n      SubprotocolRegistry::default(),\n  )\n  .await?;\n```\n\n## Split\n\n```rust\n// A split operation will only fail if the WebSocket is already closed.\nlet (mut sender, mut receiver) = websocket.split()?;\n    \nloop {\n    match receiver.read(\u0026mut buf).await? {\n        Message::Text =\u003e {\n            sender.write(\u0026mut buf, PayloadType::Text).await?;\n            buf.clear();\n        }\n        Message::Binary =\u003e {\n            sender.write(\u0026mut buf, PayloadType::Binary).await?;\n            buf.clear();\n        }\n        Message::Ping | Message::Pong =\u003e {}\n        Message::Close(_) =\u003e break Ok(()),\n    }\n}\n```\n\n# License\n\nRatchet is licensed under the [Apache License 2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswimos%2Fratchet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswimos%2Fratchet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswimos%2Fratchet/lists"}