Skip to main content

http_request/request/socket/websocket/
impl.rs

1use super::*;
2
3impl WebSocket {
4    fn get_url(&self) -> String {
5        self.url.as_ref().clone()
6    }
7
8    fn generate_websocket_key() -> String {
9        let mut key_bytes: [u8; 16] = [0u8; 16];
10        let now: u64 = SystemTime::now()
11            .duration_since(UNIX_EPOCH)
12            .unwrap_or_default()
13            .as_nanos() as u64;
14        let ptr: usize = &key_bytes as *const _ as usize;
15        for (i, byte) in key_bytes.iter_mut().enumerate() {
16            *byte = ((now.wrapping_add(ptr as u64).wrapping_add(i as u64)) % 256) as u8;
17        }
18        base64_encode(&key_bytes)
19    }
20
21    fn get_headers(&self) -> Vec<(String, String)> {
22        let mut headers: Vec<(String, String)> = Vec::new();
23        for (key, value) in self.header.iter() {
24            if let Some(first_value) = value.front() {
25                headers.push((key.clone(), first_value.clone()));
26            }
27        }
28        headers
29    }
30
31    async fn connect_async_internal(&self) -> Result<(), WebSocketError> {
32        if self.connected.load(Ordering::Relaxed) {
33            return Ok(());
34        }
35        let url: String = self.get_url();
36        if url.is_empty() {
37            return Err(WebSocketError::invalid_url("URL is empty"));
38        }
39        let url_obj: HttpUrlComponents = SharedWebSocketBuilder::parse_url(&url)?;
40        if let Ok(mut config) = self.config.write() {
41            config.url_obj = url_obj;
42        }
43        let timeout_duration: Duration = Duration::from_millis(
44            self.config
45                .read()
46                .map(|config| config.timeout)
47                .unwrap_or(DEFAULT_HIGH_SECURITY_READ_TIMEOUT_MS),
48        );
49        let headers: Vec<(String, String)> = self.get_headers();
50        let mut request_builder = Request::builder().uri(&url);
51        for (key, value) in &headers {
52            request_builder = request_builder.header(key, value);
53        }
54        let request: Request = request_builder.body(()).map_err(|error| {
55            WebSocketError::invalid_url(format!("Failed to build request: {error}"))
56        })?;
57        let proxy_config: Option<ProxyConfig> = self
58            .config
59            .read()
60            .ok()
61            .and_then(|config| config.proxy.clone());
62        let ws_stream: WebSocketConnectionType = if let Some(proxy_config) = proxy_config {
63            let url_obj: HttpUrlComponents = self
64                .config
65                .read()
66                .map(|config| config.url_obj.clone())
67                .unwrap_or_default();
68            let target_host: String = url_obj.host.clone().unwrap_or_default();
69            let target_port: u16 = url_obj.port.unwrap_or_default();
70            let proxy_stream: BoxAsyncReadWrite = self
71                .get_proxy_connection_stream_async(target_host.clone(), target_port, &proxy_config)
72                .await?;
73            let proxy_tunnel_stream: WebSocketProxyTunnelStream =
74                WebSocketProxyTunnelStream::new(proxy_stream);
75            let mut proxy_request_builder = Request::builder().uri(&url);
76            proxy_request_builder = proxy_request_builder
77                .header(HOST, format!("{target_host}:{target_port}"))
78                .header(UPGRADE, "websocket")
79                .header(CONNECTION, "Upgrade")
80                .header(SEC_WEBSOCKET_VERSION, "13")
81                .header(SEC_WEBSOCKET_KEY, Self::generate_websocket_key());
82            for (key, value) in &headers {
83                proxy_request_builder = proxy_request_builder.header(key, value);
84            }
85            let protocols: Vec<String> = self
86                .config
87                .read()
88                .map(|config| config.protocols.clone())
89                .unwrap_or_default();
90            if !protocols.is_empty() {
91                proxy_request_builder =
92                    proxy_request_builder.header("Sec-WebSocket-String", protocols.join(", "));
93            }
94            let proxy_request: Request = proxy_request_builder.body(()).map_err(|e| {
95                WebSocketError::invalid_url(format!("Failed to build proxy request: {e}"))
96            })?;
97            let connect_future = client_async_with_config(proxy_request, proxy_tunnel_stream, None);
98            let (ws_stream, _) = timeout(timeout_duration, connect_future)
99                .await
100                .map_err(|_| WebSocketError::timeout("Connection timeout"))?
101                .map_err(|e| {
102                    let error_msg: String = e.to_string();
103                    if error_msg.contains("tls")
104                        || error_msg.contains("TLS")
105                        || error_msg.contains("ssl")
106                        || error_msg.contains("SSL")
107                        || error_msg.contains("certificate")
108                        || error_msg.contains("handshake")
109                    {
110                        WebSocketError::tls(error_msg)
111                    } else {
112                        WebSocketError::connection(error_msg)
113                    }
114                })?;
115            WebSocketConnectionType::Proxy(ws_stream)
116        } else {
117            let connect_future = connect_async_with_config(request, None, false);
118            let (ws_stream, _) = timeout(timeout_duration, connect_future)
119                .await
120                .map_err(|_| WebSocketError::timeout("Connection timeout"))?
121                .map_err(|e| {
122                    let error_msg: String = e.to_string();
123                    if error_msg.contains("tls")
124                        || error_msg.contains("TLS")
125                        || error_msg.contains("ssl")
126                        || error_msg.contains("SSL")
127                        || error_msg.contains("certificate")
128                        || error_msg.contains("handshake")
129                    {
130                        WebSocketError::tls(error_msg)
131                    } else {
132                        WebSocketError::connection(error_msg)
133                    }
134                })?;
135            WebSocketConnectionType::Direct(ws_stream)
136        };
137        let mut connection: http_type::tokio::sync::MutexGuard<
138            '_,
139            Option<WebSocketConnectionType>,
140        > = self.connection.lock().await;
141        *connection = Some(ws_stream);
142        self.connected.store(true, Ordering::Relaxed);
143        Ok(())
144    }
145
146    async fn send_message_async(&self, message: Message) -> Result<(), WebSocketError> {
147        if !self.connected.load(Ordering::Relaxed) {
148            self.connect_async_internal().await?;
149        }
150        let mut connection: http_type::tokio::sync::MutexGuard<
151            '_,
152            Option<WebSocketConnectionType>,
153        > = self.connection.lock().await;
154        if let Some(ref mut ws_stream) = *connection {
155            ws_stream
156                .send(message)
157                .await
158                .map_err(|error: tungstenite::Error| WebSocketError::protocol(error.to_string()))?;
159        } else {
160            return Err(WebSocketError::connection("Not connected"));
161        }
162        Ok(())
163    }
164
165    fn send_message_sync(&self, message: Message) -> Result<(), WebSocketError> {
166        let rt: Runtime = Runtime::new()
167            .map_err(|error: std::io::Error| WebSocketError::io(error.to_string()))?;
168        rt.block_on(self.send_message_async(message))
169    }
170
171    async fn receive_message_async(&self) -> Result<WebSocketMessage, WebSocketError> {
172        if !self.connected.load(Ordering::Relaxed) {
173            return Err(WebSocketError::connection("Not connected"));
174        }
175        let timeout_duration: Duration = Duration::from_millis(
176            self.config
177                .read()
178                .map(|config| config.timeout)
179                .unwrap_or(DEFAULT_HIGH_SECURITY_READ_TIMEOUT_MS),
180        );
181        let mut connection: http_type::tokio::sync::MutexGuard<
182            '_,
183            Option<WebSocketConnectionType>,
184        > = self.connection.lock().await;
185        if let Some(ref mut ws_stream) = *connection {
186            let receive_future = ws_stream.next();
187            if let Some(msg_result) = timeout(timeout_duration, receive_future)
188                .await
189                .map_err(|_| WebSocketError::timeout("Receive timeout"))?
190            {
191                let message: Message = msg_result.map_err(|error: tungstenite::Error| {
192                    WebSocketError::protocol(error.to_string())
193                })?;
194                return Ok(self.convert_message(message));
195            }
196        }
197        Err(WebSocketError::connection("Connection closed"))
198    }
199
200    fn receive_message_sync(&self) -> Result<WebSocketMessage, WebSocketError> {
201        let rt: Runtime = Runtime::new()
202            .map_err(|error: std::io::Error| WebSocketError::io(error.to_string()))?;
203        rt.block_on(self.receive_message_async())
204    }
205
206    fn convert_message(&self, message: Message) -> WebSocketMessage {
207        match message {
208            Message::Text(text) => WebSocketMessage::Text(text.to_string()),
209            Message::Binary(data) => WebSocketMessage::Binary(data.to_vec()),
210            Message::Ping(data) => WebSocketMessage::Ping(data.to_vec()),
211            Message::Pong(data) => WebSocketMessage::Pong(data.to_vec()),
212            Message::Close(_) => WebSocketMessage::Close,
213            Message::Frame(_) => WebSocketMessage::Close,
214        }
215    }
216
217    async fn close_async_internal(&self) -> Result<(), WebSocketError> {
218        let mut connection: http_type::tokio::sync::MutexGuard<
219            '_,
220            Option<WebSocketConnectionType>,
221        > = self.connection.lock().await;
222        if let Some(ref mut ws_stream) = *connection {
223            ws_stream
224                .send(Message::Close(None))
225                .await
226                .map_err(|error: tungstenite::Error| WebSocketError::protocol(error.to_string()))?;
227            use futures::SinkExt;
228            ws_stream
229                .close()
230                .await
231                .map_err(|error: tungstenite::Error| WebSocketError::protocol(error.to_string()))?;
232        }
233        *connection = None;
234        self.connected.store(false, Ordering::Relaxed);
235        Ok(())
236    }
237
238    fn close_sync(&self) -> Result<(), WebSocketError> {
239        let rt: Runtime = Runtime::new()
240            .map_err(|error: std::io::Error| WebSocketError::io(error.to_string()))?;
241        rt.block_on(self.close_async_internal())
242    }
243
244    async fn get_proxy_connection_stream_async(
245        &self,
246        target_host: String,
247        target_port: u16,
248        proxy_config: &ProxyConfig,
249    ) -> Result<BoxAsyncReadWrite, WebSocketError> {
250        match proxy_config.proxy_type {
251            ProxyType::Http | ProxyType::Https => {
252                self.get_http_proxy_connection_async(target_host, target_port, proxy_config)
253                    .await
254            }
255            ProxyType::Socks5 => {
256                self.get_socks5_proxy_connection_async(target_host, target_port, proxy_config)
257                    .await
258            }
259        }
260    }
261
262    async fn get_http_proxy_connection_async(
263        &self,
264        target_host: String,
265        target_port: u16,
266        proxy_config: &ProxyConfig,
267    ) -> Result<BoxAsyncReadWrite, WebSocketError> {
268        let proxy_host_port: (String, u16) = (proxy_config.host.clone(), proxy_config.port);
269        let tcp_stream: http_type::tokio::net::TcpStream =
270            http_type::tokio::net::TcpStream::connect(proxy_host_port)
271                .await
272                .map_err(|err| WebSocketError::connection(err.to_string()))?;
273        let mut proxy_stream: BoxAsyncReadWrite = if proxy_config.proxy_type == ProxyType::Https {
274            let roots: RootCertStore = RootCertStore {
275                roots: TLS_SERVER_ROOTS.to_vec(),
276            };
277            let tls_config: ClientConfig = ClientConfig::builder()
278                .with_root_certificates(roots)
279                .with_no_client_auth();
280            let connector: TlsConnector = TlsConnector::from(Arc::new(tls_config));
281            let dns_name: ServerName<'_> = ServerName::try_from(proxy_config.host.clone())
282                .map_err(|err| WebSocketError::tls(err.to_string()))?;
283            let tls_stream: TlsStream<http_type::tokio::net::TcpStream> = connector
284                .connect(dns_name, tcp_stream)
285                .await
286                .map_err(|err| WebSocketError::tls(err.to_string()))?;
287            Box::new(tls_stream)
288        } else {
289            Box::new(tcp_stream)
290        };
291        let connect_request: String = if let (Some(username), Some(password)) =
292            (&proxy_config.username, &proxy_config.password)
293        {
294            let auth: String = format!("{username}:{password}");
295            let auth_encoded: String = base64_encode(auth.as_bytes());
296            format!(
297                "CONNECT {target_host}:{target_port} HTTP/1.1\r\nHost: {target_host}:{target_port}\r\nProxy-Authorization: Basic {auth_encoded}\r\n\r\n"
298            )
299        } else {
300            format!(
301                "CONNECT {target_host}:{target_port} HTTP/1.1\r\nHost: {target_host}:{target_port}\r\n\r\n"
302            )
303        };
304        proxy_stream
305            .write_all(connect_request.as_bytes())
306            .await
307            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
308        proxy_stream
309            .flush()
310            .await
311            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
312        let mut response_buffer: [u8; 1024] = [0u8; 1024];
313        let bytes_read: usize = proxy_stream
314            .read(&mut response_buffer)
315            .await
316            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
317        let response: Cow<'_, str> = String::from_utf8_lossy(&response_buffer[..bytes_read]);
318        if !response.starts_with("HTTP/1.1 200") && !response.starts_with("HTTP/1.0 200") {
319            return Err(WebSocketError::connection(format!(
320                "Proxy connection failed: {}",
321                response.lines().next().unwrap_or("Unknown error")
322            )));
323        }
324        Ok(proxy_stream)
325    }
326
327    async fn get_socks5_proxy_connection_async(
328        &self,
329        target_host: String,
330        target_port: u16,
331        proxy_config: &ProxyConfig,
332    ) -> Result<BoxAsyncReadWrite, WebSocketError> {
333        let proxy_host_port: (String, u16) = (proxy_config.host.clone(), proxy_config.port);
334        let mut tcp_stream: http_type::tokio::net::TcpStream =
335            http_type::tokio::net::TcpStream::connect(proxy_host_port)
336                .await
337                .map_err(|err| WebSocketError::connection(err.to_string()))?;
338        let auth_methods: Vec<u8> =
339            if proxy_config.username.is_some() && proxy_config.password.is_some() {
340                vec![0x05, 0x02, 0x00, 0x02]
341            } else {
342                vec![0x05, 0x01, 0x00]
343            };
344        tcp_stream
345            .write_all(&auth_methods)
346            .await
347            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
348        let mut response: [u8; 2] = [0u8; 2];
349        tcp_stream
350            .read_exact(&mut response)
351            .await
352            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
353        if response[0] != 0x05 {
354            return Err(WebSocketError::protocol("Invalid SOCKS5 response"));
355        }
356        match response[1] {
357            0x00 => {}
358            0x02 => {
359                if let (Some(username), Some(password)) =
360                    (&proxy_config.username, &proxy_config.password)
361                {
362                    let mut auth_request = vec![0x01];
363                    auth_request.push(username.len() as u8);
364                    auth_request.extend_from_slice(username.as_bytes());
365                    auth_request.push(password.len() as u8);
366                    auth_request.extend_from_slice(password.as_bytes());
367
368                    tcp_stream
369                        .write_all(&auth_request)
370                        .await
371                        .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
372
373                    let mut auth_response = [0u8; 2];
374                    tcp_stream
375                        .read_exact(&mut auth_response)
376                        .await
377                        .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
378
379                    if auth_response[1] != 0x00 {
380                        return Err(WebSocketError::protocol("SOCKS5 authentication failed"));
381                    }
382                } else {
383                    return Err(WebSocketError::protocol(
384                        "SOCKS5 proxy requires authentication",
385                    ));
386                }
387            }
388            0xFF => {
389                return Err(WebSocketError::protocol(
390                    "No acceptable SOCKS5 authentication methods",
391                ));
392            }
393            _ => {
394                return Err(WebSocketError::protocol(
395                    "Unsupported SOCKS5 authentication method",
396                ));
397            }
398        }
399        let mut connect_request: Vec<u8> = vec![0x05, 0x01, 0x00];
400        if target_host.parse::<Ipv4Addr>().is_ok() {
401            connect_request.push(0x01);
402            let ip: Ipv4Addr = target_host.parse().unwrap();
403            connect_request.extend_from_slice(&ip.octets());
404        } else if target_host.parse::<Ipv6Addr>().is_ok() {
405            connect_request.push(0x04);
406            let ip: Ipv6Addr = target_host.parse().unwrap();
407            connect_request.extend_from_slice(&ip.octets());
408        } else {
409            connect_request.push(0x03);
410            connect_request.push(target_host.len() as u8);
411            connect_request.extend_from_slice(target_host.as_bytes());
412        }
413        connect_request.extend_from_slice(&target_port.to_be_bytes());
414        tcp_stream
415            .write_all(&connect_request)
416            .await
417            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
418
419        let mut connect_response: [u8; 4] = [0u8; 4];
420        tcp_stream
421            .read_exact(&mut connect_response)
422            .await
423            .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
424
425        if connect_response[0] != 0x05 || connect_response[1] != 0x00 {
426            return Err(WebSocketError::protocol(format!(
427                "SOCKS5 connection failed with code: {}",
428                connect_response[1]
429            )));
430        }
431        match connect_response[3] {
432            0x01 => {
433                let mut skip: [u8; 6] = [0u8; 6];
434                tcp_stream
435                    .read_exact(&mut skip)
436                    .await
437                    .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
438            }
439            0x03 => {
440                let mut len: [u8; 1] = [0u8; 1];
441                tcp_stream
442                    .read_exact(&mut len)
443                    .await
444                    .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
445                let mut skip: Vec<u8> = vec![0u8; len[0] as usize + 2];
446                tcp_stream
447                    .read_exact(&mut skip)
448                    .await
449                    .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
450            }
451            0x04 => {
452                let mut skip: [u8; 18] = [0u8; 18];
453                tcp_stream
454                    .read_exact(&mut skip)
455                    .await
456                    .map_err(|err: std::io::Error| WebSocketError::protocol(err.to_string()))?;
457            }
458            _ => {
459                return Err(WebSocketError::protocol("Invalid SOCKS5 address type"));
460            }
461        }
462        let proxy_stream: BoxAsyncReadWrite = Box::new(tcp_stream);
463        Ok(proxy_stream)
464    }
465
466    /// Sends a text message synchronously.
467    ///
468    /// # Arguments
469    ///
470    /// - `&str` - The text message to send.
471    ///
472    /// # Returns
473    ///
474    /// - `WebSocketResult` - Result indicating success or failure.
475    pub fn send_text(&mut self, text: &str) -> WebSocketResult {
476        let message: Message = Message::Text(text.into());
477        self.send_message_sync(message)
478    }
479
480    /// Sends a binary message synchronously.
481    ///
482    /// # Arguments
483    ///
484    /// - `&[u8]` - The binary data to send.
485    ///
486    /// # Returns
487    ///
488    /// - `WebSocketResult` - Result indicating success or failure.
489    pub fn send_binary(&mut self, data: &[u8]) -> WebSocketResult {
490        let message: Message = Message::Binary(data.to_vec().into());
491        self.send_message_sync(message)
492    }
493
494    /// Sends a ping message synchronously.
495    ///
496    /// # Arguments
497    ///
498    /// - `&[u8]` - The ping data to send.
499    ///
500    /// # Returns
501    ///
502    /// - `WebSocketResult` - Result indicating success or failure.
503    pub fn send_ping(&mut self, data: &[u8]) -> WebSocketResult {
504        let message: Message = Message::Ping(data.to_vec().into());
505        self.send_message_sync(message)
506    }
507
508    /// Sends a pong message synchronously.
509    ///
510    /// # Arguments
511    ///
512    /// - `&[u8]` - The pong data to send.
513    ///
514    /// # Returns
515    ///
516    /// - `WebSocketResult` - Result indicating success or failure.
517    pub fn send_pong(&mut self, data: &[u8]) -> WebSocketResult {
518        let message: Message = Message::Pong(data.to_vec().into());
519        self.send_message_sync(message)
520    }
521
522    /// Receives a message synchronously.
523    ///
524    /// # Returns
525    ///
526    /// - `WebSocketMessageResult` - Result containing the received message or error.
527    pub fn receive(&mut self) -> WebSocketMessageResult {
528        self.receive_message_sync()
529    }
530
531    /// Closes the WebSocket connection synchronously.
532    ///
533    /// # Returns
534    ///
535    /// - `WebSocketResult` - Result indicating success or failure.
536    pub fn close(&mut self) -> WebSocketResult {
537        self.close_sync()
538    }
539
540    /// Checks if the WebSocket is currently connected.
541    ///
542    /// # Returns
543    ///
544    /// - `bool` - True if connected, false otherwise.
545    pub fn is_connected(&self) -> bool {
546        self.connected.load(Ordering::Relaxed)
547    }
548
549    /// Sends a text message asynchronously.
550    ///
551    /// # Arguments
552    ///
553    /// - `&str` - The text message to send.
554    ///
555    /// # Returns
556    ///
557    /// - `WebSocketResult` - Result indicating success or failure.
558    pub async fn send_text_async(&mut self, text: &str) -> WebSocketResult {
559        let message: Message = Message::Text(text.into());
560        self.send_message_async(message).await
561    }
562
563    /// Sends a binary message asynchronously.
564    ///
565    /// # Arguments
566    ///
567    /// - `&[u8]` - The binary data to send.
568    ///
569    /// # Returns
570    ///
571    /// - `WebSocketResult` - Result indicating success or failure.
572    pub async fn send_binary_async(&mut self, data: &[u8]) -> WebSocketResult {
573        let message: Message = Message::Binary(data.to_vec().into());
574        self.send_message_async(message).await
575    }
576
577    /// Sends a ping message asynchronously.
578    ///
579    /// # Arguments
580    ///
581    /// - `&[u8]` - The ping data to send.
582    ///
583    /// # Returns
584    ///
585    /// - `WebSocketResult` - Result indicating success or failure.
586    pub async fn send_ping_async(&mut self, data: &[u8]) -> WebSocketResult {
587        let message: Message = Message::Ping(data.to_vec().into());
588        self.send_message_async(message).await
589    }
590
591    /// Sends a pong message asynchronously.
592    ///
593    /// # Arguments
594    ///
595    /// - `&[u8]` - The pong data to send.
596    ///
597    /// # Returns
598    ///
599    /// - `WebSocketResult` - Result indicating success or failure.
600    pub async fn send_pong_async(&mut self, data: &[u8]) -> WebSocketResult {
601        let message: Message = Message::Pong(data.to_vec().into());
602        self.send_message_async(message).await
603    }
604
605    /// Receives a message asynchronously.
606    ///
607    /// # Returns
608    ///
609    /// - `WebSocketMessageResult` - Result containing the received message or error.
610    pub async fn receive_async(&mut self) -> WebSocketMessageResult {
611        self.receive_message_async().await
612    }
613
614    /// Closes the WebSocket connection asynchronously.
615    ///
616    /// # Returns
617    ///
618    /// - `WebSocketResult` - Result indicating success or failure.
619    pub async fn close_async_method(&mut self) -> WebSocketResult {
620        self.close_async_internal().await
621    }
622}
623
624/// Synchronous WebSocket trait implementation.
625///
626/// Provides synchronous methods for WebSocket operations including:
627/// - Sending messages (text, binary, ping, pong)
628/// - Receiving messages
629/// - Closing connections
630/// - Checking connection status
631impl WebSocketTrait for WebSocket {
632    fn send_text(&mut self, text: &str) -> WebSocketResult {
633        self.send_text(text)
634    }
635
636    fn send_binary(&mut self, data: &[u8]) -> WebSocketResult {
637        self.send_binary(data)
638    }
639
640    fn send_ping(&mut self, data: &[u8]) -> WebSocketResult {
641        self.send_ping(data)
642    }
643
644    fn send_pong(&mut self, data: &[u8]) -> WebSocketResult {
645        self.send_pong(data)
646    }
647
648    fn receive(&mut self) -> WebSocketMessageResult {
649        self.receive()
650    }
651
652    fn close(&mut self) -> WebSocketResult {
653        self.close()
654    }
655
656    fn is_connected(&self) -> bool {
657        self.is_connected()
658    }
659}
660
661/// Asynchronous WebSocket trait implementation.
662///
663/// Provides asynchronous methods for WebSocket operations including:
664/// - Sending messages (text, binary, ping, pong)
665/// - Receiving messages
666/// - Closing connections
667/// - Checking connection status
668impl AsyncWebSocketTrait for WebSocket {
669    fn send_text<'a>(
670        &'a mut self,
671        text: &'a str,
672    ) -> Pin<Box<dyn Future<Output = WebSocketResult> + Send + 'a>> {
673        Box::pin(self.send_text_async(text))
674    }
675
676    fn send_binary<'a>(
677        &'a mut self,
678        data: &'a [u8],
679    ) -> Pin<Box<dyn Future<Output = WebSocketResult> + Send + 'a>> {
680        Box::pin(self.send_binary_async(data))
681    }
682
683    fn send_ping<'a>(
684        &'a mut self,
685        data: &'a [u8],
686    ) -> Pin<Box<dyn Future<Output = WebSocketResult> + Send + 'a>> {
687        Box::pin(self.send_ping_async(data))
688    }
689
690    fn send_pong<'a>(
691        &'a mut self,
692        data: &'a [u8],
693    ) -> Pin<Box<dyn Future<Output = WebSocketResult> + Send + 'a>> {
694        Box::pin(self.send_pong_async(data))
695    }
696
697    fn receive(&mut self) -> Pin<Box<dyn Future<Output = WebSocketMessageResult> + Send + '_>> {
698        Box::pin(self.receive_async())
699    }
700
701    fn close(&mut self) -> Pin<Box<dyn Future<Output = WebSocketResult> + Send + '_>> {
702        Box::pin(self.close_async_method())
703    }
704
705    fn is_connected(&self) -> bool {
706        self.is_connected()
707    }
708}