{"id":18622083,"url":"https://github.com/security-union/yew-websocket","last_synced_at":"2026-02-09T02:19:40.327Z","repository":{"id":65820278,"uuid":"535180837","full_name":"security-union/yew-websocket","owner":"security-union","description":"Yew Rust / Wasm  for using WebSockets","archived":false,"fork":false,"pushed_at":"2024-03-07T00:03:07.000Z","size":414,"stargazers_count":19,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T06:42:24.890Z","etag":null,"topics":["rust","rust-lang","yew","yew-framework"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/security-union.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2022-09-11T03:31:30.000Z","updated_at":"2024-11-08T03:16:39.000Z","dependencies_parsed_at":"2024-03-04T22:08:30.358Z","dependency_job_id":null,"html_url":"https://github.com/security-union/yew-websocket","commit_stats":{"total_commits":12,"total_committers":4,"mean_commits":3.0,"dds":"0.41666666666666663","last_synced_commit":"65ba14335963d5ec8e3ea2bb0de4b89e611f2b7c"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/security-union%2Fyew-websocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/security-union%2Fyew-websocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/security-union%2Fyew-websocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/security-union%2Fyew-websocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/security-union","download_url":"https://codeload.github.com/security-union/yew-websocket/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335418,"owners_count":21086588,"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":["rust","rust-lang","yew","yew-framework"],"created_at":"2024-11-07T04:15:19.605Z","updated_at":"2026-02-09T02:19:35.969Z","avatar_url":"https://github.com/security-union.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Ww0Xt1mAMy31Ofar0GYu8Oab0v2k0uF1XT_zTt5kPU1M8o58sT5OOXCsSxv3nNGxsG8dG4zI=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj (1)](https://user-images.githubusercontent.com/1176339/155262320-ce1406f0-d35d-418e-a8b9-60b928cceeb2.jpeg)\n\n# yew-websocket\n[![crates.io](https://img.shields.io/crates/v/yew-websocket.svg)](https://crates.io/crates/yew-websocket)\n[![docs.rs](https://docs.rs/yew-websocket/badge.svg)](https://docs.rs/yew-websocket)\n\nRust yew websocket service written with love :)\n\nSupports yew version 0.20.0\n\nThis crate is based on the original yew websocket service that used to be part of the core library.\nhttps://github.com/yewstack/yew/blob/0.18.0/packages/yew/src/services/websocket.rs\n\nFor some reason, the core team decided to kill it.\n\nI tried using the suggested libraries (wasm-sockets or gloo-net), but those are not properly integrated with yew.\n\n## Sample\n\n```rust\nuse anyhow::Error;\nuse serde_derive::{Deserialize, Serialize};\nuse yew_websocket::macros::Json;\n\nuse yew::{html, Component, Context, Html};\nuse yew_websocket::websocket::{WebSocketService, WebSocketStatus, WebSocketTask};\n\ntype AsBinary = bool;\n\npub enum Format {\n    Json,\n    Toml,\n}\n\npub enum WsAction {\n    Connect,\n    SendData(AsBinary),\n    Disconnect,\n    Lost,\n}\n\npub enum Msg {\n    WsAction(WsAction),\n    WsReady(Result\u003cWsResponse, Error\u003e),\n}\n\nimpl From\u003cWsAction\u003e for Msg {\n    fn from(action: WsAction) -\u003e Self {\n        Msg::WsAction(action)\n    }\n}\n\n/// This type is used as a request which sent to websocket connection.\n#[derive(Serialize, Debug)]\nstruct WsRequest {\n    value: u32,\n}\n\n/// This type is an expected response from a websocket connection.\n#[derive(Deserialize, Debug)]\npub struct WsResponse {\n    value: u32,\n}\n\npub struct Model {\n    pub fetching: bool,\n    pub data: Option\u003cu32\u003e,\n    pub ws: Option\u003cWebSocketTask\u003e,\n}\n\nimpl Model {\n    fn view_data(\u0026self) -\u003e Html {\n        if let Some(value) = self.data {\n            html! {\n                \u003cp\u003e{ value }\u003c/p\u003e\n            }\n        } else {\n            html! {\n                \u003cp\u003e{ \"Data hasn't fetched yet.\" }\u003c/p\u003e\n            }\n        }\n    }\n}\n\nimpl Component for Model {\n    type Message = Msg;\n    type Properties = ();\n\n    fn create(ctx: \u0026Context\u003cSelf\u003e) -\u003e Self {\n        Self {\n            fetching: false,\n            data: None,\n            ws: None,\n        }\n    }\n\n    fn update(\u0026mut self, ctx: \u0026Context\u003cSelf\u003e, msg: Self::Message) -\u003e bool {\n        match msg {\n            Msg::WsAction(action) =\u003e match action {\n                WsAction::Connect =\u003e {\n                    let callback = ctx.link().callback(|Json(data)| Msg::WsReady(data));\n                    let notification = ctx.link().batch_callback(|status| match status {\n                        WebSocketStatus::Opened =\u003e None,\n                        WebSocketStatus::Closed | WebSocketStatus::Error =\u003e {\n                            Some(WsAction::Lost.into())\n                        }\n                    });\n                    let task = WebSocketService::connect(\n                        \"wss://echo.websocket.events/\",\n                        callback,\n                        notification,\n                    )\n                    .unwrap();\n                    self.ws = Some(task);\n                    true\n                }\n                WsAction::SendData(binary) =\u003e {\n                    let request = WsRequest { value: 321 };\n                    if binary {\n                        self.ws.as_mut().unwrap().send_binary(Json(\u0026request));\n                    } else {\n                        self.ws.as_mut().unwrap().send(Json(\u0026request));\n                    }\n                    false\n                }\n                WsAction::Disconnect =\u003e {\n                    self.ws.take();\n                    true\n                }\n                WsAction::Lost =\u003e {\n                    self.ws = None;\n                    true\n                }\n            },\n            Msg::WsReady(response) =\u003e {\n                self.data = response.map(|data| data.value).ok();\n                true\n            }\n        }\n    }\n\n    fn view(\u0026self, ctx: \u0026Context\u003cSelf\u003e) -\u003e Html {\n        html! {\n            \u003cdiv\u003e\n                \u003cnav class=\"menu\"\u003e\n                    { self.view_data() }\n                    \u003cbutton disabled={self.ws.is_some()}\n                            onclick={ctx.link().callback(|_| WsAction::Connect)}\u003e\n                        { \"Connect To WebSocket\" }\n                    \u003c/button\u003e\n                    \u003cbutton disabled={self.ws.is_none()}\n                            onclick={ctx.link().callback(|_| WsAction::SendData(false))}\u003e\n                        { \"Send To WebSocket\" }\n                    \u003c/button\u003e\n                    \u003cbutton disabled={self.ws.is_none()}\n                            onclick={ctx.link().callback(|_| WsAction::SendData(true))}\u003e\n                        { \"Send To WebSocket [binary]\" }\n                    \u003c/button\u003e\n                    \u003cbutton disabled={self.ws.is_none()}\n                            onclick={ctx.link().callback(|_| WsAction::Disconnect)}\u003e\n                        { \"Close WebSocket connection\" }\n                    \u003c/button\u003e\n                \u003c/nav\u003e\n            \u003c/div\u003e\n        }\n    }\n}\n\nfn main() {\n    yew::Renderer::\u003cModel\u003e::new().render();\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurity-union%2Fyew-websocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecurity-union%2Fyew-websocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurity-union%2Fyew-websocket/lists"}