{"id":17209357,"url":"https://github.com/de-vri-es/hyper-tungstenite-rs","last_synced_at":"2025-05-16T07:02:48.880Z","repository":{"id":37690240,"uuid":"336650680","full_name":"de-vri-es/hyper-tungstenite-rs","owner":"de-vri-es","description":"websockets for hyper servers, backed by tungstenite","archived":false,"fork":false,"pushed_at":"2024-12-18T16:21:31.000Z","size":68,"stargazers_count":51,"open_issues_count":2,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-08T23:05:45.071Z","etag":null,"topics":["async","hacktoberfest","hyper","rust","websocket"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/de-vri-es.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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-02-06T22:33:07.000Z","updated_at":"2025-04-18T11:15:19.000Z","dependencies_parsed_at":"2023-11-19T10:23:55.554Z","dependency_job_id":"34a363d3-7ab3-4b72-949c-a5944ee6b364","html_url":"https://github.com/de-vri-es/hyper-tungstenite-rs","commit_stats":{"total_commits":77,"total_committers":10,"mean_commits":7.7,"dds":"0.24675324675324672","last_synced_commit":"3f0fbbd9fca2c80675567f3cdc4233f975b75a2f"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/de-vri-es%2Fhyper-tungstenite-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/de-vri-es%2Fhyper-tungstenite-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/de-vri-es%2Fhyper-tungstenite-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/de-vri-es%2Fhyper-tungstenite-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/de-vri-es","download_url":"https://codeload.github.com/de-vri-es/hyper-tungstenite-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485029,"owners_count":22078767,"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","hacktoberfest","hyper","rust","websocket"],"created_at":"2024-10-15T02:51:23.838Z","updated_at":"2025-05-16T07:02:48.816Z","avatar_url":"https://github.com/de-vri-es.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Docs.rs](https://docs.rs/hyper-tungstenite/badge.svg)](https://docs.rs/crate/hyper-tungstenite/)\n[![CI](https://github.com/de-vri-es/hyper-tungstenite-rs/workflows/CI/badge.svg)](https://github.com/de-vri-es/hyper-tungstenite-rs/actions?query=workflow%3ACI+branch%3Amain)\n\n# hyper-tungstenite\n\nThis crate allows [`hyper`](https://docs.rs/hyper) servers to accept websocket connections, backed by [`tungstenite`](https://docs.rs/tungstenite).\n\nThe [`upgrade`] function allows you to upgrade a HTTP connection to a websocket connection.\nIt returns a HTTP response to send to the client, and a future that resolves to a [`WebSocketStream`].\nThe response must be sent to the client for the future to be resolved.\nIn practise this means that you must spawn the future in a different task.\n\nNote that the [`upgrade`] function itself does not check if the request is actually an upgrade request.\nFor simple cases, you can check this using the [`is_upgrade_request`] function before calling [`upgrade`].\nFor more complicated cases where the server should support multiple upgrade protocols,\nyou can manually inspect the `Connection` and `Upgrade` headers.\n\n## Example\n```rust\nuse futures::sink::SinkExt;\nuse futures::stream::StreamExt;\nuse http_body_util::Full;\nuse hyper::body::{Bytes, Incoming};\nuse hyper::{Request, Response};\nuse hyper_tungstenite::{tungstenite, HyperWebsocket};\nuse hyper_util::rt::TokioIo;\nuse tungstenite::Message;\n\ntype Error = Box\u003cdyn std::error::Error + Send + Sync + 'static\u003e;\n\n/// Handle a HTTP or WebSocket request.\nasync fn handle_request(mut request: Request\u003cIncoming\u003e) -\u003e Result\u003cResponse\u003cFull\u003cBytes\u003e\u003e, Error\u003e {\n    // Check if the request is a websocket upgrade request.\n    if hyper_tungstenite::is_upgrade_request(\u0026request) {\n        let (response, websocket) = hyper_tungstenite::upgrade(\u0026mut request, None)?;\n\n        // Spawn a task to handle the websocket connection.\n        tokio::spawn(async move {\n            if let Err(e) = serve_websocket(websocket).await {\n                eprintln!(\"Error in websocket connection: {e}\");\n            }\n        });\n\n        // Return the response so the spawned future can continue.\n        Ok(response)\n    } else {\n        // Handle regular HTTP requests here.\n        Ok(Response::new(Full::\u003cBytes\u003e::from(\"Hello HTTP!\")))\n    }\n}\n\n/// Handle a websocket connection.\nasync fn serve_websocket(websocket: HyperWebsocket) -\u003e Result\u003c(), Error\u003e {\n    let mut websocket = websocket.await?;\n    while let Some(message) = websocket.next().await {\n        match message? {\n            Message::Text(msg) =\u003e {\n                println!(\"Received text message: {msg}\");\n                websocket.send(Message::text(\"Thank you, come again.\")).await?;\n            },\n            Message::Binary(msg) =\u003e {\n                println!(\"Received binary message: {msg:02X?}\");\n                websocket.send(Message::binary(b\"Thank you, come again.\".to_vec())).await?;\n            },\n            Message::Ping(msg) =\u003e {\n                // No need to send a reply: tungstenite takes care of this for you.\n                println!(\"Received ping message: {msg:02X?}\");\n            },\n            Message::Pong(msg) =\u003e {\n                println!(\"Received pong message: {msg:02X?}\");\n            }\n            Message::Close(msg) =\u003e {\n                // No need to send a reply: tungstenite takes care of this for you.\n                if let Some(msg) = \u0026msg {\n                    println!(\"Received close message with code {} and message: {}\", msg.code, msg.reason);\n                } else {\n                    println!(\"Received close message\");\n                }\n            },\n            Message::Frame(_msg) =\u003e {\n                unreachable!();\n            }\n        }\n    }\n\n    Ok(())\n}\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c(), Error\u003e {\n    let addr: std::net::SocketAddr = \"[::1]:3000\".parse()?;\n    let listener = tokio::net::TcpListener::bind(\u0026addr).await?;\n    println!(\"Listening on http://{addr}\");\n\n    let mut http = hyper::server::conn::http1::Builder::new();\n    http.keep_alive(true);\n\n    loop {\n        let (stream, _) = listener.accept().await?;\n        let connection = http\n            .serve_connection(TokioIo::new(stream), hyper::service::service_fn(handle_request))\n            .with_upgrades();\n        tokio::spawn(async move {\n            if let Err(err) = connection.await {\n                println!(\"Error serving HTTP connection: {err:?}\");\n            }\n        });\n    }\n}\n```\n\n[`upgrade`]: https://docs.rs/hyper-tungstenite/latest/hyper_tungstenite/fn.upgrade.html\n[`WebSocketStream`]: https://docs.rs/hyper-tungstenite/latest/hyper_tungstenite/struct.WebSocketStream.html\n[`is_upgrade_request`]: https://docs.rs/hyper-tungstenite/latest/hyper_tungstenite/fn.is_upgrade_request.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fde-vri-es%2Fhyper-tungstenite-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fde-vri-es%2Fhyper-tungstenite-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fde-vri-es%2Fhyper-tungstenite-rs/lists"}