├── .gitignore ├── .cargo └── config.toml ├── Cargo.toml ├── .github └── workflows │ └── rust.yml ├── README.md ├── src ├── bench.rs └── main.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [registries.crates-io] 2 | protocol = "sparse" 3 | 4 | [env] 5 | RUSTFLAGS = "-C codegen-units=1 -C opt-level=3" 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "web-socket-benchmark" 4 | version = "0.1.0" 5 | 6 | [dependencies] 7 | futures-util = { version = "0.3", default-features = false } 8 | tokio = { version = "1", default-features = false } 9 | 10 | fastwebsockets = "0.4" 11 | soketto = "*" 12 | tokio-tungstenite = "*" 13 | web-socket = { git = "https://github.com/nurmohammed840/websocket.rs.git", branch = "main" } 14 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ '*' ] 6 | 7 | pull_request: 8 | branches: [ master ] 9 | 10 | env: 11 | CARGO_TERM_COLOR: always 12 | 13 | 14 | jobs: 15 | bench: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | 21 | - name: Build 22 | run: cargo build -r 23 | 24 | - name: Run benchmark I 25 | run: cargo run -r 26 | 27 | - name: Run benchmark II 28 | run: cargo run -r 29 | 30 | - name: Run benchmark III 31 | run: cargo run -r 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Candidates 2 | 3 | - [fastwebsockets](https://github.com/denoland/fastwebsockets) 4 | - [soketto](https://github.com/paritytech/soketto) 5 | - [tokio-tungstenite](https://github.com/snapview/tokio-tungstenite) 6 | - [web-socket](https://github.com/nurmohammed840/websocket.rs) 7 | 8 | ### Run benchmark 9 | 10 | ```bash 11 | cargo r -r 12 | ``` 13 | 14 | ### Results 15 | 16 | #### [Intel® Core™ i9-13900K Processor](https://www.intel.com/content/www/us/en/products/sku/230496/intel-core-i913900k-processor-36m-cache-up-to-5-80-ghz/specifications.html) - [@AurevoirXavier](https://github.com/AurevoirXavier) 17 | ``` 18 | fastwebsockets (send): 3.1261ms 19 | fastwebsockets (echo): 8.080872ms 20 | fastwebsockets (recv): 5.525353ms 21 | fastwebsockets: 16.732845ms 22 | 23 | 24 | soketto (send): 7.998258ms 25 | soketto (echo): 18.857447ms 26 | soketto (recv): 10.228193ms 27 | soketto: 37.08868ms 28 | 29 | 30 | tokio_tungstenite (send): 7.722288ms 31 | tokio_tungstenite (echo): 17.284609ms 32 | tokio_tungstenite (recv): 10.407554ms 33 | tokio_tungstenite: 35.427836ms 34 | 35 | 36 | web-socket (send): 2.369528ms 37 | web-socket (echo): 6.243006ms 38 | web-socket (recv): 3.372092ms 39 | web-socket: 11.985043ms 40 | ``` 41 | -------------------------------------------------------------------------------- /src/bench.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io, 3 | pin::{pin, Pin}, 4 | task::{Context, Poll}, 5 | }; 6 | 7 | use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; 8 | 9 | pub struct Stream { 10 | is_client: bool, 11 | server_read_pos: usize, 12 | client_read_pos: usize, 13 | server: Vec, 14 | client: Vec, 15 | } 16 | 17 | impl Stream { 18 | pub fn new(capacity: usize) -> Self { 19 | Self { 20 | server: Vec::with_capacity(capacity), 21 | client: Vec::with_capacity(capacity), 22 | server_read_pos: 0, 23 | client_read_pos: 0, 24 | is_client: true, 25 | } 26 | } 27 | 28 | pub fn role_server(&mut self) { 29 | self.is_client = false 30 | } 31 | pub fn role_client(&mut self) { 32 | self.is_client = true 33 | } 34 | 35 | fn _poll_write(&mut self, _: &mut Context, buf: &[u8]) -> Poll> { 36 | if self.is_client { 37 | self.server.extend_from_slice(buf) 38 | } else { 39 | self.client.extend_from_slice(buf) 40 | } 41 | Poll::Ready(Ok(buf.len())) 42 | } 43 | 44 | fn _poll_write_vectored( 45 | &mut self, 46 | _: &mut Context, 47 | bufs: &[io::IoSlice], 48 | ) -> Poll> { 49 | Poll::Ready(io::Write::write_vectored( 50 | if self.is_client { 51 | &mut self.server 52 | } else { 53 | &mut self.client 54 | }, 55 | bufs, 56 | )) 57 | } 58 | } 59 | 60 | impl futures_util::AsyncRead for Stream { 61 | fn poll_read( 62 | mut self: Pin<&mut Self>, 63 | cx: &mut Context, 64 | buf: &mut [u8], 65 | ) -> Poll> { 66 | if self.is_client { 67 | let pos = self.client_read_pos; 68 | let res = futures_util::AsyncRead::poll_read(pin!(&self.client[pos..]), cx, buf); 69 | self.client_read_pos += buf.len(); 70 | res 71 | } else { 72 | let pos = self.server_read_pos; 73 | let res = futures_util::AsyncRead::poll_read(pin!(&self.server[pos..]), cx, buf); 74 | self.server_read_pos += buf.len(); 75 | res 76 | } 77 | } 78 | } 79 | impl futures_util::AsyncWrite for Stream { 80 | fn poll_write( 81 | mut self: Pin<&mut Self>, 82 | cx: &mut Context, 83 | buf: &[u8], 84 | ) -> Poll> { 85 | self._poll_write(cx, buf) 86 | } 87 | 88 | fn poll_write_vectored( 89 | mut self: Pin<&mut Self>, 90 | cx: &mut Context, 91 | bufs: &[io::IoSlice], 92 | ) -> Poll> { 93 | self._poll_write_vectored(cx, bufs) 94 | } 95 | 96 | fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll> { 97 | Poll::Ready(Ok(())) 98 | } 99 | 100 | fn poll_close(self: Pin<&mut Self>, _: &mut Context) -> Poll> { 101 | Poll::Ready(Ok(())) 102 | } 103 | } 104 | 105 | impl AsyncRead for Stream { 106 | fn poll_read( 107 | mut self: Pin<&mut Self>, 108 | cx: &mut Context, 109 | buf: &mut ReadBuf, 110 | ) -> Poll> { 111 | if self.is_client { 112 | let pos = self.client_read_pos; 113 | let res = AsyncRead::poll_read(pin!(&self.client[pos..]), cx, buf); 114 | self.client_read_pos += buf.filled().len(); 115 | res 116 | } else { 117 | let pos = self.server_read_pos; 118 | let res = AsyncRead::poll_read(pin!(&self.server[pos..]), cx, buf); 119 | self.server_read_pos += buf.filled().len(); 120 | res 121 | } 122 | } 123 | } 124 | impl AsyncWrite for Stream { 125 | fn poll_write( 126 | mut self: Pin<&mut Self>, 127 | cx: &mut Context, 128 | buf: &[u8], 129 | ) -> Poll> { 130 | self._poll_write(cx, buf) 131 | } 132 | 133 | fn poll_write_vectored( 134 | mut self: Pin<&mut Self>, 135 | cx: &mut Context, 136 | bufs: &[io::IoSlice], 137 | ) -> Poll> { 138 | self._poll_write_vectored(cx, bufs) 139 | } 140 | 141 | fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll> { 142 | Poll::Ready(Ok(())) 143 | } 144 | 145 | fn is_write_vectored(&self) -> bool { 146 | true 147 | } 148 | 149 | fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context) -> Poll> { 150 | Poll::Ready(Ok(())) 151 | } 152 | } 153 | 154 | // ------------------------- 155 | 156 | use std::task::*; 157 | 158 | static DATA: () = (); 159 | static VTABLE: RawWakerVTable = RawWakerVTable::new(|_| raw_waker(), no_op, no_op, no_op); 160 | fn raw_waker() -> RawWaker { 161 | RawWaker::new(&DATA, &VTABLE) 162 | } 163 | 164 | fn no_op(_: *const ()) {} 165 | 166 | pub fn block_on(mut fut: Fut) -> Fut::Output 167 | where 168 | Fut: std::future::Future, 169 | { 170 | let waker = unsafe { Waker::from_raw(raw_waker()) }; 171 | let mut cx = Context::from_waker(&waker); 172 | let mut fut = std::pin::pin!(fut); 173 | loop { 174 | match fut.as_mut().poll(&mut cx) { 175 | Poll::Ready(output) => break output, 176 | Poll::Pending => {} 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod bench; 2 | 3 | use std::time::Instant; 4 | 5 | const ITER: usize = 100000; 6 | const MSG: &str = "Hello, World!\n"; 7 | const CAPACITY: usize = (MSG.len() + 14) * ITER; 8 | 9 | const HELP: &str = "Please run with `--release` flag for accurate results. 10 | Example: 11 | cargo run --release 12 | cargo run -r -- -C codegen-units=1 -C opt-level=3 13 | "; 14 | 15 | fn main() { 16 | if cfg!(debug_assertions) { 17 | println!("{HELP}"); 18 | } 19 | bench::block_on(async { 20 | fastwebsockets_banchmark::run().await.unwrap(); 21 | soketto_benchmark::run().await.unwrap(); 22 | tokio_tungstenite_banchmark::run().await.unwrap(); 23 | web_socket_banchmark::run().await.unwrap(); 24 | }); 25 | } 26 | 27 | mod fastwebsockets_banchmark { 28 | use super::*; 29 | 30 | use fastwebsockets::*; 31 | 32 | type DynErr = Box; 33 | type Result = std::result::Result; 34 | 35 | pub async fn run() -> Result<()> { 36 | let mut stream = bench::Stream::new(CAPACITY); 37 | let total = Instant::now(); 38 | 39 | // ------------------------------------------------ 40 | stream.role_client(); 41 | 42 | let mut ws = WebSocket::after_handshake(&mut stream, Role::Client); 43 | ws.set_auto_pong(true); 44 | ws.set_writev(true); 45 | ws.set_auto_close(true); 46 | 47 | let send = Instant::now(); 48 | 49 | for _ in 0..ITER { 50 | ws.write_frame(Frame::new(true, OpCode::Text, None, MSG.as_bytes().into())) 51 | .await?; 52 | } 53 | ws.write_frame(Frame::new(true, OpCode::Close, None, (&[] as &[u8]).into())) 54 | .await?; 55 | 56 | let send = send.elapsed(); 57 | 58 | // ------------------------------------------------ 59 | stream.role_server(); 60 | 61 | let mut ws = WebSocket::after_handshake(&mut stream, Role::Server); 62 | ws.set_auto_apply_mask(true); 63 | ws.set_auto_pong(true); 64 | ws.set_writev(true); 65 | ws.set_auto_close(true); 66 | 67 | let echo = Instant::now(); 68 | let mut ws = FragmentCollector::new(ws); 69 | loop { 70 | let frame = ws.read_frame().await?; 71 | match frame.opcode { 72 | OpCode::Close => break, 73 | OpCode::Text | OpCode::Binary => { 74 | ws.write_frame(frame).await?; 75 | } 76 | _ => {} 77 | } 78 | } 79 | let echo = echo.elapsed(); 80 | 81 | // ----------------------------------------------- 82 | stream.role_client(); 83 | 84 | let mut ws = WebSocket::after_handshake(&mut stream, Role::Client); 85 | let recv = Instant::now(); 86 | for _ in 0..ITER { 87 | let frame = ws.read_frame().await?; 88 | assert!(frame.fin); 89 | assert_eq!(frame.opcode, OpCode::Text); 90 | assert_eq!(frame.payload, MSG.as_bytes()); 91 | } 92 | assert_eq!(ws.read_frame().await.unwrap().opcode, OpCode::Close); 93 | let recv = recv.elapsed(); 94 | 95 | // ------------------------------------------------ 96 | let total = total.elapsed(); 97 | 98 | println!("\n"); 99 | println!("fastwebsockets (send): {send:?}"); 100 | println!("fastwebsockets (echo): {echo:?}"); 101 | println!("fastwebsockets (recv): {recv:?}"); 102 | println!("fastwebsockets: {total:?}",); 103 | Ok(()) 104 | } 105 | } 106 | 107 | mod soketto_benchmark { 108 | use super::*; 109 | 110 | use soketto::{handshake::Client, Incoming}; 111 | 112 | type DynErr = Box; 113 | type Result = std::result::Result; 114 | 115 | pub async fn run() -> Result<()> { 116 | let mut stream = bench::Stream::new(CAPACITY); 117 | let total = Instant::now(); 118 | 119 | // ------------------------------------------------ 120 | stream.role_client(); 121 | 122 | let (mut ws, _) = Client::new(&mut stream, "", "").into_builder().finish(); 123 | let send = Instant::now(); 124 | for _ in 0..ITER { 125 | ws.send_text(MSG).await?; 126 | } 127 | ws.close().await?; 128 | let send = send.elapsed(); 129 | drop(ws); 130 | 131 | // ------------------------------------------------ 132 | stream.role_server(); 133 | 134 | let (mut tx, mut rx) = Client::new(&mut stream, "", "").into_builder().finish(); 135 | let echo = Instant::now(); 136 | loop { 137 | let mut msg = Vec::new(); 138 | match rx.receive(&mut msg).await? { 139 | Incoming::Data(data) => match data { 140 | soketto::Data::Text(len) => { 141 | tx.send_text(std::str::from_utf8(&msg[..len]).unwrap()) 142 | .await? 143 | } 144 | soketto::Data::Binary(len) => tx.send_binary(&msg[..len]).await?, 145 | }, 146 | Incoming::Closed(_) => break, 147 | _ => {} 148 | } 149 | } 150 | let echo = echo.elapsed(); 151 | drop(tx); 152 | drop(rx); 153 | 154 | // ------------------------------------------------ 155 | stream.role_client(); 156 | 157 | let (_, mut ws) = Client::new(&mut stream, "", "").into_builder().finish(); 158 | let recv = Instant::now(); 159 | for _ in 0..ITER { 160 | let mut msg = Vec::new(); 161 | let ty = ws.receive(&mut msg).await.unwrap(); 162 | assert!(matches!(ty, Incoming::Data(soketto::Data::Text(_)))); 163 | assert_eq!(std::str::from_utf8(&msg), Ok(MSG)); 164 | } 165 | assert!(matches!( 166 | ws.receive(&mut Vec::new()).await, 167 | Ok(Incoming::Closed(_)) 168 | )); 169 | let recv = recv.elapsed(); 170 | 171 | // ------------------------------------------------ 172 | let total = total.elapsed(); 173 | println!("\n"); 174 | println!("soketto (send): {send:?}"); 175 | println!("soketto (echo): {echo:?}"); 176 | println!("soketto (recv): {recv:?}"); 177 | println!("soketto: {total:?}",); 178 | Ok(()) 179 | } 180 | } 181 | 182 | mod tokio_tungstenite_banchmark { 183 | use super::*; 184 | 185 | use futures_util::{SinkExt, StreamExt}; 186 | use tokio_tungstenite::{ 187 | tungstenite::{protocol::Role, Message, Result}, 188 | WebSocketStream, 189 | }; 190 | 191 | pub async fn run() -> Result<()> { 192 | let mut stream = bench::Stream::new(CAPACITY); 193 | let total = Instant::now(); 194 | 195 | // ------------------------------------------------ 196 | stream.role_client(); 197 | 198 | let mut ws = WebSocketStream::from_raw_socket(&mut stream, Role::Client, None).await; 199 | let send = Instant::now(); 200 | for _ in 0..ITER { 201 | ws.feed(Message::Text(MSG.to_owned())).await?; 202 | } 203 | ws.close(None).await?; 204 | let send = send.elapsed(); 205 | // ------------------------------------------------ 206 | stream.role_server(); 207 | 208 | let mut ws = WebSocketStream::from_raw_socket(&mut stream, Role::Server, None).await; 209 | let echo = Instant::now(); 210 | while let Some(msg) = ws.next().await { 211 | let msg = msg?; 212 | if msg.is_text() || msg.is_binary() { 213 | ws.feed(msg).await?; 214 | } 215 | } 216 | let echo = echo.elapsed(); 217 | // ------------------------------------------------ 218 | stream.role_client(); 219 | 220 | let mut ws = WebSocketStream::from_raw_socket(&mut stream, Role::Client, None).await; 221 | let recv = Instant::now(); 222 | for _ in 0..ITER { 223 | match ws.next().await.unwrap()? { 224 | Message::Text(data) => assert_eq!(MSG, data), 225 | _ => unimplemented!(), 226 | } 227 | } 228 | assert!(matches!(ws.next().await, Some(Ok(Message::Close(..))))); 229 | let recv = recv.elapsed(); 230 | 231 | // ------------------------------------------------ 232 | let total = total.elapsed(); 233 | println!("\n"); 234 | println!("tokio_tungstenite (send): {send:?}"); 235 | println!("tokio_tungstenite (echo): {echo:?}"); 236 | println!("tokio_tungstenite (recv): {recv:?}"); 237 | println!("tokio_tungstenite: {total:?}",); 238 | Ok(()) 239 | } 240 | } 241 | 242 | mod web_socket_banchmark { 243 | use std::io::Result; 244 | 245 | use super::*; 246 | 247 | use tokio::io::AsyncWrite; 248 | use web_socket::*; 249 | 250 | async fn send_msg(ws: &mut WebSocket, ty: MessageType, buf: &[u8]) -> Result<()> 251 | where 252 | IO: Unpin + AsyncWrite, 253 | { 254 | match ty { 255 | MessageType::Text => ws.send(std::str::from_utf8(buf).unwrap()).await, 256 | MessageType::Binary => ws.send(buf).await, 257 | } 258 | } 259 | 260 | pub async fn run() -> Result<()> { 261 | let mut stream = bench::Stream::new(CAPACITY); 262 | let total = Instant::now(); 263 | 264 | // ------------------------------------------------ 265 | stream.role_client(); 266 | 267 | let mut ws = WebSocket::client(&mut stream); 268 | let send = Instant::now(); 269 | 270 | for _ in 0..ITER { 271 | ws.send(MSG).await?; 272 | } 273 | ws.close(()).await?; 274 | 275 | let send = send.elapsed(); 276 | 277 | // ------------------------------------------------ 278 | stream.role_server(); 279 | 280 | let mut ws = WebSocket::server(&mut stream); 281 | let echo = Instant::now(); 282 | 283 | let mut buf = Vec::new(); 284 | loop { 285 | match ws.recv_event().await? { 286 | Event::Data { data, ty } => match ty { 287 | DataType::Stream(stream) => { 288 | buf.extend_from_slice(&data); 289 | if let Stream::End(ty) = stream { 290 | send_msg(&mut ws, ty, &buf).await?; 291 | buf.clear(); 292 | } 293 | } 294 | DataType::Complete(ty) => send_msg(&mut ws, ty, &data).await?, 295 | }, 296 | Event::Pong(..) => {} 297 | Event::Ping(data) => ws.send_ping(data).await?, 298 | Event::Error(..) | Event::Close { .. } => break ws.close(()).await?, 299 | } 300 | } 301 | let echo = echo.elapsed(); 302 | 303 | // ------------------------------------------------ 304 | stream.role_client(); 305 | 306 | let mut ws = WebSocket::client(&mut stream); 307 | let recv = Instant::now(); 308 | 309 | for _ in 0..ITER { 310 | let Ok(Event::Data { ty, data }) = ws.recv_event().await else { panic!("invalid data") }; 311 | assert!(matches!(ty, DataType::Complete(MessageType::Text))); 312 | assert_eq!(std::str::from_utf8(&data), Ok(MSG)); 313 | } 314 | assert!(matches!(ws.recv_event().await, Ok(Event::Close { .. }))); 315 | let recv = recv.elapsed(); 316 | 317 | // ------------------------------------------------ 318 | let total = total.elapsed(); 319 | println!("\n"); 320 | println!("web-socket (send): {send:?}"); 321 | println!("web-socket (echo): {echo:?}"); 322 | println!("web-socket (recv): {recv:?}"); 323 | println!("web-socket: {total:?}",); 324 | Ok(()) 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.1.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 10 | 11 | [[package]] 12 | name = "base64" 13 | version = "0.13.1" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 16 | 17 | [[package]] 18 | name = "block-buffer" 19 | version = "0.9.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 22 | dependencies = [ 23 | "generic-array", 24 | ] 25 | 26 | [[package]] 27 | name = "block-buffer" 28 | version = "0.10.4" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 31 | dependencies = [ 32 | "generic-array", 33 | ] 34 | 35 | [[package]] 36 | name = "byteorder" 37 | version = "1.4.3" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 40 | 41 | [[package]] 42 | name = "bytes" 43 | version = "1.4.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 46 | 47 | [[package]] 48 | name = "cc" 49 | version = "1.0.79" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 52 | 53 | [[package]] 54 | name = "cfg-if" 55 | version = "1.0.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 58 | 59 | [[package]] 60 | name = "cpufeatures" 61 | version = "0.2.5" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 64 | dependencies = [ 65 | "libc", 66 | ] 67 | 68 | [[package]] 69 | name = "crypto-common" 70 | version = "0.1.6" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 73 | dependencies = [ 74 | "generic-array", 75 | "typenum", 76 | ] 77 | 78 | [[package]] 79 | name = "digest" 80 | version = "0.9.0" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 83 | dependencies = [ 84 | "generic-array", 85 | ] 86 | 87 | [[package]] 88 | name = "digest" 89 | version = "0.10.6" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 92 | dependencies = [ 93 | "block-buffer 0.10.4", 94 | "crypto-common", 95 | ] 96 | 97 | [[package]] 98 | name = "fastwebsockets" 99 | version = "0.4.0" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "1bccbce7916e5acbc9af10bfcc206a3fffa0de1604fd4cc2e23178f422e988b8" 102 | dependencies = [ 103 | "cc", 104 | "rand", 105 | "simdutf8", 106 | "tokio", 107 | "utf-8", 108 | ] 109 | 110 | [[package]] 111 | name = "fnv" 112 | version = "1.0.7" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 115 | 116 | [[package]] 117 | name = "form_urlencoded" 118 | version = "1.1.0" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 121 | dependencies = [ 122 | "percent-encoding", 123 | ] 124 | 125 | [[package]] 126 | name = "futures" 127 | version = "0.3.27" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" 130 | dependencies = [ 131 | "futures-channel", 132 | "futures-core", 133 | "futures-io", 134 | "futures-sink", 135 | "futures-task", 136 | "futures-util", 137 | ] 138 | 139 | [[package]] 140 | name = "futures-channel" 141 | version = "0.3.27" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" 144 | dependencies = [ 145 | "futures-core", 146 | "futures-sink", 147 | ] 148 | 149 | [[package]] 150 | name = "futures-core" 151 | version = "0.3.27" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" 154 | 155 | [[package]] 156 | name = "futures-io" 157 | version = "0.3.28" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 160 | 161 | [[package]] 162 | name = "futures-sink" 163 | version = "0.3.27" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" 166 | 167 | [[package]] 168 | name = "futures-task" 169 | version = "0.3.27" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" 172 | 173 | [[package]] 174 | name = "futures-util" 175 | version = "0.3.27" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" 178 | dependencies = [ 179 | "futures-channel", 180 | "futures-core", 181 | "futures-io", 182 | "futures-sink", 183 | "futures-task", 184 | "memchr", 185 | "pin-project-lite", 186 | "pin-utils", 187 | "slab", 188 | ] 189 | 190 | [[package]] 191 | name = "generic-array" 192 | version = "0.14.6" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 195 | dependencies = [ 196 | "typenum", 197 | "version_check", 198 | ] 199 | 200 | [[package]] 201 | name = "getrandom" 202 | version = "0.2.8" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 205 | dependencies = [ 206 | "cfg-if", 207 | "libc", 208 | "wasi", 209 | ] 210 | 211 | [[package]] 212 | name = "http" 213 | version = "0.2.9" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 216 | dependencies = [ 217 | "bytes", 218 | "fnv", 219 | "itoa", 220 | ] 221 | 222 | [[package]] 223 | name = "httparse" 224 | version = "1.8.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 227 | 228 | [[package]] 229 | name = "idna" 230 | version = "0.3.0" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 233 | dependencies = [ 234 | "unicode-bidi", 235 | "unicode-normalization", 236 | ] 237 | 238 | [[package]] 239 | name = "itoa" 240 | version = "1.0.6" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 243 | 244 | [[package]] 245 | name = "libc" 246 | version = "0.2.140" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" 249 | 250 | [[package]] 251 | name = "log" 252 | version = "0.4.17" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 255 | dependencies = [ 256 | "cfg-if", 257 | ] 258 | 259 | [[package]] 260 | name = "memchr" 261 | version = "2.5.0" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 264 | 265 | [[package]] 266 | name = "mio" 267 | version = "0.8.6" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" 270 | dependencies = [ 271 | "libc", 272 | "log", 273 | "wasi", 274 | "windows-sys", 275 | ] 276 | 277 | [[package]] 278 | name = "opaque-debug" 279 | version = "0.3.0" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 282 | 283 | [[package]] 284 | name = "percent-encoding" 285 | version = "2.2.0" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 288 | 289 | [[package]] 290 | name = "pin-project-lite" 291 | version = "0.2.9" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 294 | 295 | [[package]] 296 | name = "pin-utils" 297 | version = "0.1.0" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 300 | 301 | [[package]] 302 | name = "ppv-lite86" 303 | version = "0.2.17" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 306 | 307 | [[package]] 308 | name = "proc-macro2" 309 | version = "1.0.53" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" 312 | dependencies = [ 313 | "unicode-ident", 314 | ] 315 | 316 | [[package]] 317 | name = "quote" 318 | version = "1.0.26" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 321 | dependencies = [ 322 | "proc-macro2", 323 | ] 324 | 325 | [[package]] 326 | name = "rand" 327 | version = "0.8.5" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 330 | dependencies = [ 331 | "libc", 332 | "rand_chacha", 333 | "rand_core", 334 | ] 335 | 336 | [[package]] 337 | name = "rand_chacha" 338 | version = "0.3.1" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 341 | dependencies = [ 342 | "ppv-lite86", 343 | "rand_core", 344 | ] 345 | 346 | [[package]] 347 | name = "rand_core" 348 | version = "0.6.4" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 351 | dependencies = [ 352 | "getrandom", 353 | ] 354 | 355 | [[package]] 356 | name = "sha-1" 357 | version = "0.9.8" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" 360 | dependencies = [ 361 | "block-buffer 0.9.0", 362 | "cfg-if", 363 | "cpufeatures", 364 | "digest 0.9.0", 365 | "opaque-debug", 366 | ] 367 | 368 | [[package]] 369 | name = "sha1" 370 | version = "0.10.5" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" 373 | dependencies = [ 374 | "cfg-if", 375 | "cpufeatures", 376 | "digest 0.10.6", 377 | ] 378 | 379 | [[package]] 380 | name = "simdutf8" 381 | version = "0.1.4" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" 384 | 385 | [[package]] 386 | name = "slab" 387 | version = "0.4.8" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 390 | dependencies = [ 391 | "autocfg", 392 | ] 393 | 394 | [[package]] 395 | name = "socket2" 396 | version = "0.4.9" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 399 | dependencies = [ 400 | "libc", 401 | "winapi", 402 | ] 403 | 404 | [[package]] 405 | name = "soketto" 406 | version = "0.7.1" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" 409 | dependencies = [ 410 | "base64", 411 | "bytes", 412 | "futures", 413 | "httparse", 414 | "log", 415 | "rand", 416 | "sha-1", 417 | ] 418 | 419 | [[package]] 420 | name = "syn" 421 | version = "2.0.9" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "0da4a3c17e109f700685ec577c0f85efd9b19bcf15c913985f14dc1ac01775aa" 424 | dependencies = [ 425 | "proc-macro2", 426 | "quote", 427 | "unicode-ident", 428 | ] 429 | 430 | [[package]] 431 | name = "thiserror" 432 | version = "1.0.40" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 435 | dependencies = [ 436 | "thiserror-impl", 437 | ] 438 | 439 | [[package]] 440 | name = "thiserror-impl" 441 | version = "1.0.40" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 444 | dependencies = [ 445 | "proc-macro2", 446 | "quote", 447 | "syn", 448 | ] 449 | 450 | [[package]] 451 | name = "tinyvec" 452 | version = "1.6.0" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 455 | dependencies = [ 456 | "tinyvec_macros", 457 | ] 458 | 459 | [[package]] 460 | name = "tinyvec_macros" 461 | version = "0.1.1" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 464 | 465 | [[package]] 466 | name = "tokio" 467 | version = "1.26.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" 470 | dependencies = [ 471 | "autocfg", 472 | "bytes", 473 | "libc", 474 | "memchr", 475 | "mio", 476 | "pin-project-lite", 477 | "socket2", 478 | "windows-sys", 479 | ] 480 | 481 | [[package]] 482 | name = "tokio-tungstenite" 483 | version = "0.18.0" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" 486 | dependencies = [ 487 | "futures-util", 488 | "log", 489 | "tokio", 490 | "tungstenite", 491 | ] 492 | 493 | [[package]] 494 | name = "tungstenite" 495 | version = "0.18.0" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" 498 | dependencies = [ 499 | "base64", 500 | "byteorder", 501 | "bytes", 502 | "http", 503 | "httparse", 504 | "log", 505 | "rand", 506 | "sha1", 507 | "thiserror", 508 | "url", 509 | "utf-8", 510 | ] 511 | 512 | [[package]] 513 | name = "typenum" 514 | version = "1.16.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 517 | 518 | [[package]] 519 | name = "unicode-bidi" 520 | version = "0.3.13" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 523 | 524 | [[package]] 525 | name = "unicode-ident" 526 | version = "1.0.8" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 529 | 530 | [[package]] 531 | name = "unicode-normalization" 532 | version = "0.1.22" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 535 | dependencies = [ 536 | "tinyvec", 537 | ] 538 | 539 | [[package]] 540 | name = "url" 541 | version = "2.3.1" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 544 | dependencies = [ 545 | "form_urlencoded", 546 | "idna", 547 | "percent-encoding", 548 | ] 549 | 550 | [[package]] 551 | name = "utf-8" 552 | version = "0.7.6" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 555 | 556 | [[package]] 557 | name = "version_check" 558 | version = "0.9.4" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 561 | 562 | [[package]] 563 | name = "wasi" 564 | version = "0.11.0+wasi-snapshot-preview1" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 567 | 568 | [[package]] 569 | name = "web-socket" 570 | version = "0.7.0" 571 | source = "git+https://github.com/nurmohammed840/websocket.rs.git?branch=main#e2510ea0384c7a9baec096d48adfe448848b6c44" 572 | dependencies = [ 573 | "rand", 574 | "tokio", 575 | ] 576 | 577 | [[package]] 578 | name = "web-socket-benchmark" 579 | version = "0.1.0" 580 | dependencies = [ 581 | "fastwebsockets", 582 | "futures-util", 583 | "soketto", 584 | "tokio", 585 | "tokio-tungstenite", 586 | "web-socket", 587 | ] 588 | 589 | [[package]] 590 | name = "winapi" 591 | version = "0.3.9" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 594 | dependencies = [ 595 | "winapi-i686-pc-windows-gnu", 596 | "winapi-x86_64-pc-windows-gnu", 597 | ] 598 | 599 | [[package]] 600 | name = "winapi-i686-pc-windows-gnu" 601 | version = "0.4.0" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 604 | 605 | [[package]] 606 | name = "winapi-x86_64-pc-windows-gnu" 607 | version = "0.4.0" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 610 | 611 | [[package]] 612 | name = "windows-sys" 613 | version = "0.45.0" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 616 | dependencies = [ 617 | "windows-targets", 618 | ] 619 | 620 | [[package]] 621 | name = "windows-targets" 622 | version = "0.42.2" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 625 | dependencies = [ 626 | "windows_aarch64_gnullvm", 627 | "windows_aarch64_msvc", 628 | "windows_i686_gnu", 629 | "windows_i686_msvc", 630 | "windows_x86_64_gnu", 631 | "windows_x86_64_gnullvm", 632 | "windows_x86_64_msvc", 633 | ] 634 | 635 | [[package]] 636 | name = "windows_aarch64_gnullvm" 637 | version = "0.42.2" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 640 | 641 | [[package]] 642 | name = "windows_aarch64_msvc" 643 | version = "0.42.2" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 646 | 647 | [[package]] 648 | name = "windows_i686_gnu" 649 | version = "0.42.2" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 652 | 653 | [[package]] 654 | name = "windows_i686_msvc" 655 | version = "0.42.2" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 658 | 659 | [[package]] 660 | name = "windows_x86_64_gnu" 661 | version = "0.42.2" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 664 | 665 | [[package]] 666 | name = "windows_x86_64_gnullvm" 667 | version = "0.42.2" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 670 | 671 | [[package]] 672 | name = "windows_x86_64_msvc" 673 | version = "0.42.2" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 676 | --------------------------------------------------------------------------------