ws2/
lib.rs

1//!
2//!# Very Simple Websocket For Rust
3//!
4//!`ws2` is a very easy to use WebSocket server & client for Rust, builds on `ws` crate. it was designed for production, the receive timeout provides a non-blocking way.
5//!
6//!## Server Example
7//!
8//!```rust
9//!use log2::*;
10//!use ws2::{Pod, WebSocket};
11//!
12//!struct Worker;
13//!
14//!impl ws2::Handler for Worker {
15//!    fn on_open(&mut self, ws: &WebSocket) -> Pod {
16//!        info!("on open: {ws}");
17//!        Ok(())
18//!    }
19//!
20//!    fn on_close(&mut self, ws: &WebSocket) -> Pod {
21//!        info!("on close: {ws}");
22//!        Ok(())
23//!    }
24//!
25//!    fn on_message(&mut self, ws: &WebSocket, msg: String) -> Pod {
26//!        info!("on message: {msg}, {ws}");
27//!        let echo = format!("echo: {msg}");
28//!        let n = ws.send(echo);
29//!        Ok(n?)
30//!    }
31//!}
32//!
33//!fn main() -> Pod {
34//!    let _log2 = log2::start();
35//!    let address = "127.0.0.1:3125";
36//!    let mut worker = Worker {};
37//!
38//!    info!("listen on: {address}");
39//!    let mut server = ws2::listen(address)?;
40//!
41//!    loop {
42//!        let _ = server.process(&mut worker, 0.5);
43//!        // do other stuff
44//!    }
45//!}
46//!
47//!```
48//!
49//!## Client Example
50//!
51//!The websocket client was designed as out-of-the-box, it will auto reconnect every 3s.
52//!
53//!```rust
54//!use log2::*;
55//!use ws2::{Pod, WebSocket};
56//!
57//!struct Worker;
58//!
59//!impl ws2::Handler for Worker {
60//!    fn on_open(&mut self, ws: &WebSocket) -> Pod {
61//!        // ws.send("Hello World")?;
62//!        info!("on open: {ws}");
63//!        Ok(())
64//!    }
65//!
66//!    fn on_close(&mut self, ws: &WebSocket) -> Pod {
67//!        info!("on close: {ws}");
68//!        Ok(())
69//!    }
70//!
71//!    fn on_message(&mut self, ws: &WebSocket, msg: String) -> Pod {
72//!        info!("on message: {msg}, {ws}");
73//!        Ok(())
74//!    }
75//!}
76//!
77//!fn main() -> Pod {
78//!    let _log2 = log2::start();
79//!    let url = "wss://stream.binance.com:9443/ws/btcusdt@miniTicker";
80//!    let mut client = ws2::connect(url);
81//!    let mut workder = Worker {};
82//!
83//!    loop {
84//!        let _ = client.process(&mut workder, 0.5);
85//!        // do other stuff
86//!    }
87//!}
88//!```
89//!
90pub mod client;
91pub mod server;
92
93use std::fmt::Display;
94use ws::{Error, Message, Result};
95
96/// Flexible result
97pub type Pod = anyhow::Result<(), anyhow::Error>;
98
99/// Wait infinitely
100pub const INFINITE: f32 = std::f32::MAX;
101
102pub use client::connect;
103pub use client::Client;
104pub use server::listen;
105pub use server::Server;
106pub use ws::Sender;
107
108#[derive(Clone)]
109/// WebSocket sender
110pub struct WebSocket {
111    address: String,
112    id: u32,
113    sender: Sender,
114}
115
116impl WebSocket {
117    #[inline]
118    /// send string or binary
119    pub fn send<M>(&self, msg: M) -> Result<()>
120    where
121        M: Into<Message>,
122    {
123        self.sender.send(msg)
124    }
125
126    /// peer address
127    pub fn address(&self) -> &str {
128        &self.address
129    }
130
131    /// unique websocket id
132    pub fn id(&self) -> u32 {
133        self.id
134    }
135
136    /// close the websocket
137    pub fn close(&self) -> Pod {
138        let n = self.sender.close(ws::CloseCode::Normal);
139        Ok(n?)
140    }
141}
142
143impl Display for WebSocket {
144    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145        write!(f, "{}", self.address)
146    }
147}
148
149#[allow(unused)]
150pub trait Handler {
151    fn on_open(&mut self, ws: &WebSocket) -> Pod {
152        Ok(())
153    }
154
155    fn on_close(&mut self, ws: &WebSocket) -> Pod {
156        Ok(())
157    }
158
159    fn on_message(&mut self, ws: &WebSocket, msg: String) -> Pod {
160        Ok(())
161    }
162
163    fn on_binary(&mut self, ws: &WebSocket, buf: Vec<u8>) -> Pod {
164        Ok(())
165    }
166
167    fn on_error(&mut self, error: Error) -> Pod {
168        Ok(())
169    }
170
171    fn on_timeout(&mut self) -> Pod {
172        Ok(())
173    }
174}