Skip to main content

http_request/request/socket/websocket/
impl.rs

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