
    di                       d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZmZmZmZmZmZ d
dlmZmZ d
dlmZmZm Z m!Z! d
dl"m#Z#m$Z$ d
dl%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ ddl%m,Z,m-Z- erd dl.m/Z/ d
dlm0Z0 d
dl"m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9 ddl:m;Z;m<Z<  ed      Z=ede>e1gdf   Z?edee>e@f   gdf   ZAede$gdf   ZBedgdf   ZCedeDe@gdf   ZEeFee>eGf   eDf   ZHeFe>ee!eDf   f   ZI eed      Z G d de      ZJ G d  d!e$      ZK G d" d#eKe(      ZL G d$ d%eKe)      ZM G d& d'      ZNed(   ZO G d) deN      ZP G d* d+eN      ZQy),    )annotationsN)Callable)suppress)IntEnum)partial)dumpsloads)select)TYPE_CHECKINGAnyClassVarLiteralOptionalTypeVarUnion   )CURL_SOCKET_BADget_selector)	CurlECodeCurlInfoCurlOpt
CurlWsFlag)Curl	CurlError)CurlCffiWarning   )SessionClosedTimeout)Response)not_setset_curl_options)Self)CurlHttpVersion)CurlWsFrame)CookieTypes)HeaderTypes)BrowserTypeLiteralExtraFingerprintsExtraFpDict)AsyncSession	ProxySpecT	WebSocket),:)
separatorsc                  X    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZy)WsCloseCodez?See: https://www.iana.org/assignments/websocket/websocket.xhtml  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  N)__name__
__module____qualname____doc__OK
GOING_AWAYPROTOCOL_ERRORUNSUPPORTED_DATAUNKNOWNABNORMAL_CLOSUREINVALID_DATAPOLICY_VIOLATIONMESSAGE_TOO_BIGMANDATORY_EXTENSIONINTERNAL_ERRORSERVICE_RESTARTTRY_AGAIN_LATERBAD_GATEWAYTLS_HANDSHAKEUNAUTHORIZED	FORBIDDENTIMEOUT     T/root/funda.leads/venv/lib/python3.12/site-packages/curl_cffi/requests/websockets.pyr2   r2   0   sc    I	BJNGLONOOKMLIGrK   r2   c                  .     e Zd ZdZ	 d	 	 	 d fdZ xZS )WebSocketErrorzWebSocket-specific error.c                &    t         |   ||       y N)super__init__)selfmessagecode	__class__s      rL   rR   zWebSocketError.__init__J   s     	$'rK   )r   )rT   strrU   z)Union[WsCloseCode, CurlECode, Literal[0]])r4   r5   r6   r7   rR   __classcell__rV   s   @rL   rN   rN   G   s'    # OP(("K( (rK   rN   c                      e Zd ZdZy)WebSocketClosedzWebSocket is already closed.Nr4   r5   r6   r7   rJ   rK   rL   r[   r[   P   s    &rK   r[   c                      e Zd ZdZy)WebSocketTimeoutzWebSocket operation timed out.Nr\   rJ   rK   rL   r^   r^   T   s    (rK   r^   c                  ~    e Zd ZdZdddddZed        Zedd       Zedd       Ze	dd	       Z
e	dd
       Zd Zy)BaseWebSocket_curl	autoclose_close_code_close_reasondebugclosedTF)rc   rf   c               X    || _         || _        d | _        d | _        || _        d| _        y )NFra   )rS   curlrc   rf   s       rL   rR   zBaseWebSocket.__init__b   s.    
(*.,0
rK   c                t    | j                   t        u rt        | j                        | _         | j                   S )N)rf   )rb   r    r   rf   rS   s    rL   ri   zBaseWebSocket.curlj   s(    :: DJJ/DJzzrK   c                    | j                   S )z<The WebSocket close code, if the connection has been closed.)rd   rk   s    rL   
close_codezBaseWebSocket.close_codep   s     rK   c                    | j                   S )z>The WebSocket close reason, if the connection has been closed.)re   rk   s    rL   close_reasonzBaseWebSocket.close_reasonu   s     !!!rK   c                4    t        j                  d|       |z   S )N!H)structpack)rU   reasons     rL   _pack_close_framezBaseWebSocket._pack_close_framez   s    {{4&//rK   c                   t        |       dk  rt        j                  }d}||fS 	 t        j                  d|       d   }| dd  j                         }|t        j                  k(  s
|dk  s|dk\  rt        d| t        j                        ||fS # t        $ r }t        dt        j                        |d }~wt        $ r }t        d	t        j                        |d }~ww xY w)
Nr    rq   r   r3   i  zInvalid close code: zInvalid close messagezInvalid close frame)lenr2   r<   rr   unpack_fromdecoderN   r:   UnicodeDecodeErrorr>   	Exception)framerU   rt   es       rL   _unpack_close_framez!BaseWebSocket._unpack_close_frame~   s    u:>&&DF$ V|!))$6q9qr))+ ;...$+(.tf5{7Q7Q  V| & $+[-E-E  $);+E+Es#   ,B 	C B44C  CC c                F    d| _         | j                  j                          y)z$Terminate the underlying connection.TN)rg   ri   closerk   s    rL   	terminatezBaseWebSocket.terminate   s    		rK   N)ri   r   rc   boolrf   r   )returnzOptional[int])r   Optional[str])rU   intrt   bytesr   r   )r}   r   r   ztuple[int, str])r4   r5   r6   	__slots__rR   propertyri   rm   ro   staticmethodru   r   r   rJ   rK   rL   r`   r`   X   s~    I 9=E   
     " " 0 0  .rK   r`   )openr   datarT   errorc                      e Zd ZdZdZefddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZd dZd!d	Zd"d
Z	ddddedddddddddddddddddddf	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d#dZ
d$dZd%dZd&dZedd'dZej"                  f	 	 	 d(dZd)dZd)dZd*dZedd+dZd,dZd-d.dZej6                  dfd/dZ xZS )0r-   z)A WebSocket implementation using libcurl.)skip_utf8_validation	_emitterskeep_runningTFN)rc   r   rf   on_openon_closeon_data
on_messageon_errorc                   t         
|   |||       || _        d| _        i | _        |r|| j                  d<   |r|| j                  d<   |r|| j                  d<   |r|| j                  d<   |	r|	| j                  d<   yy)	a|  
        Args:
            autoclose: whether to close the WebSocket after receiving a close frame.
            skip_utf8_validation: whether to skip UTF-8 validation for text frames in
                run_forever().
            debug: print extra curl debug info.

            on_open: open callback, ``def on_open(ws)``
            on_close: close callback, ``def on_close(ws, code, reason)``
            on_data: raw data receive callback, ``def on_data(ws, data, frame)``
            on_message: message receive callback, ``def on_message(ws, message)``
            on_error: error callback, ``def on_error(ws, exception)``
        ri   rc   rf   Fr   r   r   rT   r   N)rQ   rR   r   r   r   )rS   ri   rc   r   rf   r   r   r   r   r   rV   s             rL   rR   zWebSocket.__init__   s    4 	diuE$8!!;=%,DNN6"&.DNN7#%,DNN6"(2DNN9%&.DNN7# rK   c                4    | j                   rt        d      | S )NWebSocket is closedrg   r[   rk   s    rL   __iter__zWebSocket.__iter__   s    ;;!"788rK   c                ^    | j                         \  }}|t        j                  z  rt        |S rP   )recvr   CLOSEStopIterationrS   msgflagss      rL   __next__zWebSocket.__next__   s*    YY[
U:###
rK   c                   | j                   j                  |      }|r	  || g|  y y # t        $ rV}| j                   j                  d      }|r
 || |       n%t        j                  d| dt
        d       Y d }~y Y d }~y d }~ww xY w)Nr   zWebSocket callback 'z' failedr   
stacklevel)r   getr|   warningswarnr   )rS   
event_typeargscallbackr~   error_callbacks         rL   _emitzWebSocket._emit   s    >>%%j1%%   	!%!3!3G!<!"4+MM.zl(C'#$  ,	s   	* 	B	ABB	   zgzip, deflate, brrw   r   c                F   | j                   }t        di d|ddd|dd|gdd|gdd|gd	|d
|d|d|dd|	gd|
d|dd|gd|d|d|d|d|d|d|d|d|d|d|d|d| |j                  t        j                  d       |j                          | S ) a	  Connect to the WebSocket.

        libcurl automatically handles pings and pongs.
        ref: https://curl.se/libcurl/c/libcurl-ws.html

        Args:
            url: url for the requests.
            params: query string for the requests.
            headers: headers to send.
            cookies: cookies to use.
            auth: HTTP basic auth, a tuple of (username, password), only basic auth is
                supported.
            timeout: how many seconds to wait before giving up.
            allow_redirects: whether to allow redirection.
            max_redirects: max redirect counts, default 30, use -1 for unlimited.
            proxies: dict of proxies to use, prefer to use ``proxy`` if they are the
                same. format: ``{"http": proxy_url, "https": proxy_url}``.
            proxy: proxy to use, format: "http://user@pass:proxy_url".
                Can't be used with `proxies` parameter.
            proxy_auth: HTTP basic auth for proxy, a tuple of (username, password).
            verify: whether to verify https certs.
            referer: shortcut for setting referer header.
            accept_encoding: shortcut for setting accept-encoding header.
            impersonate: which browser version to impersonate.
            ja3: ja3 string to impersonate.
            akamai: akamai string to impersonate.
            extra_fp: extra fingerprints options, in complement to ja3 and akamai str.
            default_headers: whether to set default browser headers.
            default_encoding: encoding for decoding response content if charset is not
                found in headers. Defaults to "utf-8". Can be set to a callable for
                automatic detection.
            quote: Set characters to be quoted, i.e. percent-encoded. Default safe
                string is ``!#$%&'()*+,/:;=?@[]~``. If set to a sting, the character
                will be removed from the safe string, thus quoted. If set to False, the
                url will be kept as is, without any automatic percent-encoding, you must
                encode the URL yourself.
            curl_options: extra curl options to use.
            http_version: limiting http version, defaults to http2.
            interface: which interface to use.
            cert: a tuple of (cert, key) filenames for client cert.
            max_recv_speed: maximum receive speed, bytes per second.
            curl_options: extra curl options to use.
        ri   methodGETurlparams_listNheaders_listcookies_listauthtimeoutallow_redirectsmax_redirectsproxies_listproxy
proxy_authverify_listrefereraccept_encodingimpersonateja3akamaiextra_fpdefault_headersquotehttp_version	interfacemax_recv_speedcertcurl_optionsr   rJ   )ri   r!   setoptr   CONNECT_ONLYperform)rS   r   paramsheaderscookiesr   r   r   r   proxiesr   r   verifyr   r   r   r   r   r   r   r   r   r   r   r   r   ri   s                              rL   connectzWebSocket.connect   sX   P yy 	
	
	
 	
 v		

 	
 	
 	
 	
 ,	
 (	
 	
 	
 "	
 v	
 	
  ,!	
" $#	
$ %	
& '	
( )	
* ,+	
, -	
. &/	
0  1	
2 *3	
4 5	
6 &7	
> 	G((!,rK   c                   | j                   rt        d      | j                  j                         \  }}|j                  t
        j                  z  r;	 | j                  |      \  | _        | _	        | j                  r| j                          ||fS # t        $ r2}|j                  | _        | j                  |j                          d}~ww xY w)z2Receive a single curl websocket fragment as bytes.WebSocket is already closedN)rg   r[   ri   ws_recvr   r   r   r   rd   re   rN   rU   r   rc   )rS   chunkr}   r~   s       rL   recv_fragmentzWebSocket.recv_fragmentZ  s     ;;!"?@@yy((*u;;)))7;7O7OPU7V4 $"4 ~~

e| "  $%66 

166"s   B 	C-CCc                
   g }d}| j                   j                  t        j                        }|t        k(  rt        dt        j                        	 	 | j                         \  }}|j                  }|j                  |       |j                  dk(  r|t        j                  z  dk(  rnXdj%                  |      |fS # t        $ r<}|j                  t        j                   k(  rt#        |gg g d      \  }}}n Y d}~Td}~ww xY w)z
        Receive a frame as bytes. libcurl splits frames into fragments, so we have to
        collect all the chunks for a frame.
        r   Invalid active socket      ?NrK   )ri   getinfor   ACTIVESOCKETr   rN   r   NO_CONNECTION_AVAILABLEr   r   append	bytesleftr   CONTr   rU   AGAINr
   join)rS   chunksr   sock_fdr   r}   r~   _s           rL   r   zWebSocket.recvp  s    
 ))##H$9$9:o% ')J)J  #113ue$??a'EJOO,Cq,H   xx&&  66Y__, %gYB<GAq! 	s   AB= =	D2C==Dc                    | j                         \  }}|t        j                  z  st        dt        j
                        |j                         S )zReceive a text frame.zNot valid text frame)r   r   TEXTrN   r2   r>   rz   )rS   r   r   s      rL   recv_strzWebSocket.recv_str  s=    iike
' !79Q9QRR{{}rK   )r	   c               2    | j                         } ||      S )zeReceive a JSON frame.

        Args:
            loads: JSON decoder, default is json.loads.
        )r   )rS   r	   r   s      rL   	recv_jsonzWebSocket.recv_json  s     }}T{rK   c                v   |t         j                  z  rd| _        | j                  rt	        d      t        |t              r|j                         }| j                  j                  t        j                        }|t        k(  rt        dt        j                        d}|t!        |      k  r6||d }	 | j                  j#                  ||      }||z  }|t!        |      k  r6|S # t$        $ rI}|j&                  t        j(                  k(  r&t+        g |gg d      \  }}	}|	st        d      |Y d}~ d}~ww xY w)zuSend a data frame.

        Args:
            payload: data to send.
            flags: flags for the frame.
        Fr   r   r   Nr   zSocket write timeout)r   r   r   rg   r[   
isinstancerW   encoderi   r   r   r   r   rN   r   r   rx   ws_sendr   rU   r   r
   )
rS   payloadr   r   offsetcurrent_buffern_sentr~   r   	writeables
             rL   sendzWebSocket.send  s+    :### %D;;!"?@@ gs#nn&G))##H$9$9:o% ')J)J  s7|#$VW-N**>5A fF s7|#   66Y__,&,R'B&DOAy!$,-CD!Ks   4C& &	D8/>D32D33D8c                B    | j                  |t        j                        S )zVSend a binary frame.

        Args:
            payload: binary data to send.
        r   r   BINARYrS   r   s     rL   send_binaryzWebSocket.send_binary       yy*"3"344rK   c                B    | j                  |t        j                        S )ztSend a binary frame, alias of :meth:`send_binary`.

        Args:
            payload: binary data to send.
        r   r   s     rL   
send_byteszWebSocket.send_bytes  r   rK   c                B    | j                  |t        j                        S )zRSend a text frame.

        Args:
            payload: text data to send.
        r   r   r   r   s     rL   send_strzWebSocket.send_str       yy*//22rK   r   c               0    | j                   ||            S )zSend a JSON frame.

        Args:
            payload: data to send.
            dumps: JSON encoder, default is json.dumps.
        r  rS   r   r   s      rL   	send_jsonzWebSocket.send_json  s     }}U7^,,rK   c                B    | j                  |t        j                        S )zMSend a ping frame.

        Args:
            payload: data to send.
        r   r   PINGr   s     rL   pingzWebSocket.ping  r  rK   c                   |r | j                   |fi | | j                  j                  t        j                        }|t
        k(  rt        dt        j                        | j                  d       g }d| _
        | j                  rK	 | j                         \  }}|j                  }| j                  d||       |j                  |       |j                  dk(  r|t        j                   z  dk(  swd| j"                  v rydj%                  |      }|t        j&                  z  r| j(                  s	 |j+                         }|t        j6                  z  s|t        j&                  z  r| j                  d|       g }|t        j8                  z  r6d
| _
        | j                  d| j2                  xs d| j:                  xs d       | j                  rJy	y	# t,        $ rT}	t.        j0                  | _        | j5                  t.        j0                         t        dt.        j0                        |	d	}	~	ww xY w# t<        $ r}	|	j>                  t        j@                  k(  rtC        |gg g d      \  }
}
}
n\| j                  d|	       | jD                  s=t.        jF                  }tI        |	t              r|	j>                  }| j5                  |        Y d	}	~	d	}	~	ww xY w)zRun the WebSocket forever. See :meth:`connect` for details on parameters.

        libcurl automatically handles pings and pongs.
        ref: https://curl.se/libcurl/c/libcurl-ws.html
        r   r   Tr   r   rT   rK   zInvalid UTF-8NFr   rw   r   r   )%r   ri   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rz   r{   r2   r>   rd   r   r   r   re   r   rU   r   r
   rg   r<   r   )rS   r   kwargsr   r   r   r}   r   r   r~   r   rU   s               rL   run_foreverzWebSocket.run_forever  sY    DLL''))##H$9$9:o% ')J)J  	

6  +#113u

65%0e$1,1HA1M .((6*C
/9R9R%"%**,C 
 1 11uz7N

9c2:+++(-D%JJw(8(8(=At?Q?Q?WUWXA $  2 %/:/G/GD, JJ{'?'?@"0 /1I1I##$%%   
66Y__,$gYB<GAq!JJw*;;*22%a8#$66D

4( 
sF   
A(H5 3>H5 2G BH5 	H2AH--H22H5 5	K>BKKrK   c                    | j                   t        u ry| j                  ||      }| j                  |t        j
                         | j                          y)znClose the connection.

        Args:
            code: close code.
            message: close reason.
        N)ri   r    ru   r   r   r   r   )rS   rU   rT   r   s       rL   r   zWebSocket.close<  sE     99 $$T73		#z''(rK   )ri   zUnion[Curl, Any]rc   r   r   r   rf   r   r   zOptional[ON_OPEN_T]r   zOptional[ON_CLOSE_T]r   zOptional[ON_DATA_T]r   zOptional[ON_MESSAGE_T]r   zOptional[ON_ERROR_T])r   r-   r   r   )r   EventTypeLiteralr   None)2r   rW   r   z"Optional[Union[dict, list, tuple]]r   zOptional[HeaderTypes]r   zOptional[CookieTypes]r   Optional[tuple[str, str]]r   z3Optional[Union[float, tuple[float, float], object]]r   r   r   r   r   zOptional[ProxySpec]r   r   r   r  r   zOptional[bool]r   r   r   r   r   zOptional[BrowserTypeLiteral]r   r   r   r   r   z/Optional[Union[ExtraFingerprints, ExtraFpDict]]r   r   r   zUnion[str, Literal[False]]r   zOptional[CurlHttpVersion]r   r   r   z%Optional[Union[str, tuple[str, str]]]r   r   r   zOptional[dict[CurlOpt, str]])r   ztuple[bytes, CurlWsFrame])r   ztuple[bytes, int])r   rW   )r	   zCallable[[str], T]r   r,   )r   zUnion[str, bytes, memoryview]r   r   )r   r   )r   rW   )r   r   r   Callable[[Any], str]r   zUnion[str, bytes])rw   )r   rW   )rU   r   rT   r   )r4   r5   r6   r7   r   r    rR   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r  r   r  r  r  r2   r8   r   rX   rY   s   @rL   r-   r-      s{   3I ")(/ %*'+)-'+-1)-(/(/ 	(/
 #(/ (/ %(/ '(/ %(/ +(/ '(/T
& 6:)-)-*.GN $'+#04!%!%)<48! $DH $,.26#'6:595kk 3k '	k
 'k (k Ek k k %k k .k k k 'k  2!k" #k$ %k& B'k( )k* *+k, 0-k. !/k0 41k2 3k4 35kZ,'@ 8=  '---.- -^553 HM -3BH !,  rK   c                      e Zd ZU dZdZdZded<   dZded<   dZd	ed
<   ddddddddddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1 fdZ	e
d2d       Ze
d3d       Zd4dZd5dZd6dZd7dZd5dZdd	 	 	 d8dZddd9dZedd	 	 	 	 	 d:dZej.                  f	 	 	 d;d Zd<d!Zd<d"Zd=d#Zed$	 	 	 	 	 d>d%Zd?d&Zej@                  d'd(f	 	 	 	 	 	 	 d@d)Z!d5 fd*Z"d5d+Z#d5d,Z$dAd-Z%dBdCd.Z&d5 fd/Z'dDd0Z( xZ)S )EAsyncWebSocketz
    An asyncio WebSocket implementation using libcurl.

    NOTE: This object represents a single WebSocket connection. Once closed,
    it cannot be reopened. A new instance must be created to reconnect.
    )session_loop_sock_fd_close_lock_terminate_lock
_read_task_write_task_close_handle_receive_queue_send_queue_max_send_batch_size_coalesce_framesretry_on_recv_error_yield_interval_use_fair_scheduling_yield_mask_recv_error_retries_terminated_terminated_eventi  zClassVar[int]_MAX_CURL_FRAME_SIZE   _MAX_RECV_RETRIESg333333?zClassVar[float]_RECV_RETRY_DELAYTFi      gMbP??   )
rc   rf   recv_queue_sizesend_queue_sizemax_send_batch_sizecoalesce_framesr%  yield_intervalfair_scheduling
yield_maskc       
           t         |   |||       || _        d| _        d| _        t        j                         | _        t        j                         | _	        t        j                         | _        d| _        d| _        d| _        t        j                  |      | _        t        j                  |      | _        || _        || _        |	| _        |
| _        || _        || _        d| _        d| _        y)as	  Initializes an Async WebSocket session.

        This class should not be instantiated directly. It is intended to be created
        via the `AsyncSession.ws_connect()` method, which correctly handles setup and
        initialization of the underlying I/O tasks.

        Important:
            This WebSocket implementation uses a decoupled I/O model. Network
            operations occur in background tasks. As a result, network-related
            errors that occur during a `send()` operation will not be raised by
            `send()`. Instead, they are placed into the receive queue and will be
            raised by the next call to `recv()`.

        Args:
            session (AsyncSession): An instantiated AsyncSession object.
            curl (Curl): The underlying Curl to use.
            autoclose (bool, optional): Close the WS on receiving a close frame.
            debug (bool, optional): Enable debug messages. Defaults to False.
            recv_queue_size (int, optional): The maximum number of incoming WebSocket
                messages to buffer internally. This queue stores messages received
                by the Curl socket that are waiting to be consumed by calling `recv()`
            send_queue_size (int, optional): The maximum number of outgoing WebSocket
                messages to buffer before applying network backpressure. When you call
                `send(...)` the message is placed in this queue and transmitted when
                the Curl socket is next available for sending.
            max_send_batch_size (int, optional): The max number of messages per batch.
            coalesce_frames (bool, optional): Combine multiple frames into a batch.
            retry_on_recv_error (bool, optional): Retry recv on some transient errors.
            yield_interval (float, optional): How often to yield control in seconds.
            fair_scheduling (bool, optional): Change the ~5:1 ratio in favor
                of `recv`:`send` to a fairer 1:1 ratio. This decreases recv throughput.
            yield_mask (int, optional): A bitmask that sets the yield frequency for
                cooperative multitasking, checked every `yield_mask + 1` operations.
                Must be a power of two minus one (e.g., `63`, `127`, `255`) for
                efficient bitwise checks. Lower values increase fairness; higher values
                increase throughput.
        r   N)maxsizer   F)rQ   rR   r  r  r  asyncioLockr  	threadingr  Eventr+  r  r  r   Queuer!  r"  r#  r$  r%  r&  r'  r(  r)  r*  )rS   r  ri   rc   rf   r2  r3  r4  r5  r%  r6  r7  r8  rV   s                rL   rR   zAsyncWebSocket.__init__q  s    j 	diuE/6:>
)0/8~~/?078<9=7;>Emm#?
 <C==#<
 *=!&5)< &4*9! *() !&rK   c                v    | j                   "t        t        j                               | _         | j                   S )z)Get a reference to the running event loop)r  r   r<  get_running_looprk   s    rL   loopzAsyncWebSocket.loop  s-     ::%g&>&>&@ADJzzrK   c                6    | j                   j                         S )z6Returns the current number of items in the send queue.)r"  qsizerk   s    rL   r3  zAsyncWebSocket.send_queue_size  s     %%''rK   c                    | j                   s| j                  ry| j                  r| j                  j                         ry| j                  xr | j                  j                          S )a  
        Checks if the background I/O tasks are still running.

        Returns `False` if either the read or write task has terminated due
        to an error or a clean shutdown.

        Note: This is a snapshot in time. A return value of `True` does not
        guarantee the next network operation will succeed, but `False`
        definitively indicates the connection is no longer active.
        F)rg   r*  r  doner  rk   s    rL   is_alivezAsyncWebSocket.is_alive  sR     ;;$**??t335$$@)9)9)>)>)@AArK   c                    t        | dd      ryt        t              5  t        j                  d| dt
        d       ddd       y# 1 sw Y   yxY w)z1Warn if the user forgets to close the connection.rg   TNzUnclosed WebSocket zN was garbage collected. Always call await ws.close() to ensure clean shutdown.r   r   )getattrr   r|   r   r   ResourceWarningrk   s    rL   __del__zAsyncWebSocket.__del__  sU     44(i  	MM%dX .I I		 	 	s   !AAc                4    | j                   rt        d      | S )NzWebSocket has been closedr   rk   s    rL   	__aiter__zAsyncWebSocket.__aiter__  s    ;;!"=>>rK   c                ~   K   | j                          d {   \  }}||t        j                  z  rt        |S 7 $wrP   )r   r   r   StopAsyncIterationr   s      rL   	__anext__zAsyncWebSocket.__anext__  s:     99;&
UKUZ%5%55$$
 's   =;%=c                   | j                   y| j                  j                  t        j                        | _        | j
                  t        k(  rt        dt        j                        dt        |       d}| j                  j                  | j                         | d      | _         | j                  j                  | j                         | d      | _        y)	a  Start the read/write I/O loop tasks.
        This should be called only once after object creation by the factory.
        Once started, the tasks cannot be restarted again, this is a one-shot.

        Raises:
            WebSocketError: The WebSocket FD was invalid.
        NzInvalid active socket.)rU   z
WebSocket-z#xz-read)namez-write)r  ri   r   r   r   r  r   rN   r   r   idrC  create_task
_read_loop_write_loopr  )rS   ws_ids     rL   _start_io_taskszAsyncWebSocket._start_io_tasks  s     ??& 		))(*?*?@==O+ (y/P/P 
 ""T(2/ ))//0A5'QV/X9900wf%5 1 
rK   Nr   c               |  K   | j                   r%| j                  j                         rt        d      	 t	        j
                  | j                  j                         |       d{   \  }}t        |t              r|||fS 7 # t        j                  $ r }t        dt        j                        |d}~ww xY ww)a  Receive a frame as bytes.

        This method waits for and returns the next complete data frame from the
        receive queue.

        Args:
            timeout: how many seconds to wait before giving up.

        Raises:
            WebSocketClosed: If `recv()` is called on a closed connection after
                the receive queue is empty.
            WebSocketTimeout: If the operation times out.
            WebSocketError: A protocol or network error that occurred in a
                background I/O task, including errors from previous `send()`
                operations.

        Returns:
            tuple[bytes, int]: A tuple with the received payload and flags.
        r   NzWebSocket recv() timed out)rg   r!  emptyr[   r<  wait_forr   r   r|   TimeoutErrorr^   r   OPERATION_TIMEDOUT)rS   r   resultr   r~   s        rL   r   zAsyncWebSocket.recv  s     , ;;4..446!"788
	")"2"243F3F3J3J3Lg"VVMFE&),5= 	 W ## 	",i.J.J	s:   2B<1B &B'B B<B B9B44B99B<c               "  K   | j                  |       d{   \  }}||t        j                  z  st        dt        j
                        	 |j                  d      S 7 H# t        $ r }t        dt        j
                        |d}~ww xY ww)zmReceive a text frame.

        Args:
            timeout: how many seconds to wait before giving up.
        rZ  NzNot a valid text frameutf-8zInvalid UTF-8 in text frame)r   r   r   rN   r2   r>   rz   r{   )rS   r   r   r   r~   s        rL   r   zAsyncWebSocket.recv_str8  s      !IIgI66e<
 7 !9;;S;STT	;;w''	 7
 " 	 -{/G/G	s3   BA!6BA#  B#	B,BBB)r	   r   c               >  K   | j                  |       d{   \  }}|t        dt        j                        |t        j
                  z  r	  ||j                  d            S  ||      S 7 V# t        $ r }t        dt        j                        |d}~ww xY ww)zReceive a JSON frame.

        Args:
            loads: JSON decoder, default is json.loads.
            timeout: how many seconds to wait before giving up.
        rZ  Nz(Received empty frame, cannot decode JSONrb  z Invalid UTF-8 in JSON text frame)r   rN   r2   r>   r   r   rz   r{   )rS   r	   r   r   r   r~   s         rL   r   zAsyncWebSocket.recv_jsonH  s      !IIgI66e< :K<T<T  :??"T[[122
 T{ 7 & $68P8Ps3   BA/6BA1 &
B1	B:BBBc                z  K   | j                   rt        d      t        |t              r|j	                  d      }n!t        |t
        t        f      rt        |      }	 | j                  j                  ||f       y# t        j                  $ r) | j                  j                  ||f       d{  7   Y yw xY ww)ac  Send a data frame.

        This method is a lightweight, non-blocking call that places the payload
        into a send queue. The actual network transmission is handled by a
        background task.

        To guarantee all your messages have been sent `await ws.flush(...)`.

        The max frame size supported by libcurl is `65535` bytes. Larger frames
        will be broken down and sent in chunks of that size.

        Args:
            payload: data to send.
            flags: flags for the frame.

        Raises:
            WebSocketClosed: The WebSocket is closed.

        NOTE:
            Due to the asynchronous nature of this client, network errors
            (e.g., connection dropped) that occur during the actual transmission
            will NOT be raised by this method. They will be raised by a
            subsequent call to `recv()`. Always ensure you are actively
            receiving data to handle potential connection errors.

            Also: If the network is slow and the internal send queue becomes full,
            this method will block until there is space in the queue.
        r   rb  N)rg   r[   r   rW   r   	bytearray
memoryviewr   r"  
put_nowaitr<  	QueueFullput)rS   r   r   s      rL   r   zAsyncWebSocket.sendb  s     D ;;!"788 gs#nnW-G)Z!89GnG	9''%(89   	9""&&'7888	9s6   AB;A< ;B;<3B8/B20B85B;7B88B;c                ^   K   | j                  |t        j                         d{   S 7 w)zSend a binary frame.

        Args:
            payload: binary data to send.

        For more info, see the docstring for `send(...)`
        Nr   r   s     rL   r   zAsyncWebSocket.send_binary  %      YYw
(9(9::::   $-+-c                ^   K   | j                  |t        j                         d{   S 7 w)zSend a binary frame, alias of :meth:`send_binary`.

        Args:
            payload: binary data to send.

        For more info, see the docstring for `send(...)`
        Nr   r   s     rL   r   zAsyncWebSocket.send_bytes  rk  rl  c                ^   K   | j                  |t        j                         d{   S 7 w)zSend a text frame.

        Args:
            payload: text data to send.

        For more info, see the docstring for `send(...)`
        Nr  r   s     rL   r  zAsyncWebSocket.send_str  #      YYw
8888rl  r  c               L   K   | j                   ||             d{   S 7 w)zSend a JSON frame.

        Args:
            payload: data to send.
            dumps: JSON encoder, default is `json.dumps(...)`.

        For more info, see the docstring for `send(...)`
        Nr  r  s      rL   r  zAsyncWebSocket.send_json  s!      ]]5>2222s   $"$c                ^   K   | j                  |t        j                         d{   S 7 w)zSend a ping frame.

        Args:
            payload: data to send.

        For more info, see the docstring for `send(...)`
        Nr
  r   s     rL   r  zAsyncWebSocket.ping  ro  rl  rK   g      @c           	       K   | j                   4 d{    | j                  r	 ddd      d{    yd| _        	 | j                  r| j                  j                         s| j	                  ||      }t        t        j                        5  t        j                  | j                  j                  |t        j                  f      |       d{    ddd       t        t        t              5  | j                  |       d{    ddd       | j!                          t        t        j                        5  t        j                  | j"                  j%                         |       d{    ddd       ddd      d{    y7 |7 b7 # 1 sw Y   xY w7 # 1 sw Y   xY w7 ?# 1 sw Y   >xY w# | j!                          t        t        j                        5  t        j                  | j"                  j%                         |       d{  7   ddd       w # 1 sw Y   w xY wxY w7 # 1 d{  7  sw Y   yxY ww)a#  
        Performs a graceful WebSocket closing handshake and terminates the connection.

        This method sends a WebSocket close frame to the peer, waits for queued
        outgoing messages to be sent, and then shuts down the connection. This is
        the recommended way to close the session.

        Args:
            code (int, optional): Close code. Defaults to `WsCloseCode.OK`.
            message (bytes, optional): Close reason. Defaults to `b""`.
            timeout (float, optional): How long in seconds to wait closed.
        NTrZ  )r  rg   r  rG  ru   r   r<  r^  r]  r"  ri  r   r   r^   rN   flushr   r+  wait)rS   rU   rT   r   close_frames        rL   r   zAsyncWebSocket.close  s     ## 	S 	S{{	S 	S 	S DKS##D,<,<,A,A,C"&"8"8w"GK!'"6"67 %.. ,,00+z?O?O1PQ$+  
 ""2NC 2"jj1112   g223 S!**4+A+A+F+F+H'RRRS+	S 	S 	S 	S  22 2 SS S   g223 S!**4+A+A+F+F+H'RRRS S S+	S 	S 	S 	Ss  IFIH;IFIH;AF?AFFFF?4F%	F#
F%F?)H;?2F31F12F36H;>I	H9
IIFF 	F?#F%%F.	*F?1F33F<	8H;?*H6)2H*	HH*	!	H6*H3/H66H;9I;III	Ic                     j                   5   j                  r
	 ddd       yd _         j                  r> j                  j	                         r$ j                  j                   fd       _        net         !           j                  rK j                  j                  s5 j                  j                  d        j                  j                          ddd       y# 1 sw Y   yxY w)a3  
        Immediately terminates the connection without a graceful handshake.

        This method is a forceful shutdown that cancels all background I/O tasks
        and cleans up resources. It should be used for final cleanup or after an
        unrecoverable error. Unlike `close()`, it does not attempt to send a close
        frame or wait for pending messages. It schedules the cleanup to run on the
        event loop and returns immediately. It does not wait for cleanup completion.

        This method is thread-safe, task-safe, and idempotent.
        NTc                 V     j                   j                   j                               S rP   )rC  rU  _terminate_helperrk   s   rL   <lambda>z*AsyncWebSocket.terminate.<locals>.<lambda>  s    DII11$2H2H2JK rK   )r  r*  r  rC  
is_runningcall_soon_threadsafer   rQ   r   r  _closed	push_curlr+  set)rS   rV   s   `rL   r   zAsyncWebSocket.terminate  s     !! 	1	1 	1  $D zzdii224%)YY%C%CK&" !#<<(<(<LL**40**..0#	1 	1 	1s   C%B6C%%C.c                X  K   | j                   j                  }| j                  j                  }| j                  j                  }| j
                  }| j                  }| j                  }| j                  }g }d}		 | j                  s|j                         }
	 |j                  | j                  |
j                  d       	 |
 d{    | j                  dk7  r|j/                  | j                         	 |j1                         }	 	  |       \  }}|j2                  }| j4                  dkD  rd| _        |t6        j8                  z  r|t        t         j"                        5   |||f       ddd       | j;                  |       d{    	 t        t         j"                        5   |t-        d      df       ddd       y|j=                  |       |j>                  dk  rB|t6        j@                  z  dk(  r,djC                  |      }|jE                          	  |||f       |	dz  }	|	|z  dk(  }|j1                         |z
  |kD  }|r|s|r2n|r/|r-t!        jF                  d       d{    |j1                         }{t        t         j"                        5   |t-        d      df       ddd       y# t        $ r}t        t         j"                        5   |t%        d| t&        j(                        df       ddd       n# 1 sw Y   nxY w| j+                          Y d}~t        t         j"                        5   |t-        d      df       ddd       y# 1 sw Y   yxY wd}~ww xY w7 # | j                  dk7  r|j/                  | j                         w w xY w# 1 sw Y   =xY w7 ,# 1 sw Y   yxY w# t         j"                  $ r  |||f       d{  7   Y w xY w7 # tH        $ rI}|jJ                  t&        jL                  k(  rY d}~n)|jJ                  t&        jN                  k(  ru| jP                  ri| j4                  | jR                  k  rP| xj4                  dz  c_        t!        jF                  | jT                  | j4                  z         d{  7   Y d}~t        t         j"                        5   ||df       ddd       n# 1 sw Y   nxY w| j+                          Y d}~t        t         j"                        5   |t-        d      df       ddd       y# 1 sw Y   yxY wd}~ww xY w| j                  sΐ# t         jV                  $ r Y t        $ r`}| j                  s9t        t         j"                        5   ||df       ddd       n# 1 sw Y   nxY w| j+                          Y d}~Od}~ww xY w# 1 sw Y   yxY w# t        t         j"                        5   |t-        d      df       ddd       w # 1 sw Y   w xY wxY ww)a  The main asynchronous task for reading incoming WebSocket frames.

        This method is fully event-driven. It waits for the underlying socket
        to become readable, and upon being woken by the event loop, it drains
        all buffered data from libcurl until it receives an EAGAIN error. This
        error signals that the buffer is empty, and the loop returns to an
        idle state, waiting for the next readability event.

        To ensure cooperative multitasking during high-volume message streams,
        the loop yields control to the asyncio event loop periodically.

        If the receive queue becomes full, await `self._receive_queue.put(...)`
        will block the reader loop and stall the socket read task. Thus, appropriate
        queue sizes should be set by the user, even though the defaults are generous
        and should be suitable for most use cases.
        r   Nzadd_reader failed: zConnection closed.r:  rK   r   ),rb   r   r!  rg  ri  rC  r'  r(  r&  rg   create_future
add_readerr  
set_resultr|   r   r<  rh  rN   r   r   r   r[   remove_readertimer   r)  r   r   _handle_close_framer   r   r   r   clearsleepr   rU   r   
RECV_ERRORr%  r.  r/  CancelledError)rS   curl_ws_recvqueue_put_nowait	queue_putrC  r7  r8  r6  r   msg_counterread_futureexc
start_timer   r}   r   rT   op_check
time_checkr~   s                       rL   rV  zAsyncWebSocket._read_loop  s{    & zz))..99''++	yy33%%
-- e	Mkk"002OODMM;3I3I4P:%%% }}***4==9 "YY[
:'3~u%*[[33a778D4 !:#3#33!)'*;*;!< A 0% @A"&":":5"AAA"r '++, M /2F"G!KLM Mm e, !??a/UZ__5LQR4R&)hhv&6G"LLNB 0'51A B $q(*5
*Bq)H+/99;+Cn+T
  / &"*z")--"222)-JI J '++, M /2F"G!KLM My ! !'"3"34 	( .&9#$?$-$E$E!" !"	 	 	 NN$` '++, M /2F"G!KLM M My & }}***4==9 +A AAtM M] $+#4#4 B&/%0@&A A AB 3 % 66Y__4! FFi&:&:: $ 8 8 $ 8 84;Q;Q Q 4494")-- $ 6 69Q9Q Q#   % &g&7&78 5,aV45 5 5( '++, M /2F"G!KLM M M?G kkt %% 	 	;;g//0 -$aV,- - -NN		M M'++, M /2F"G!KLM M Ms   A7X*:U 'J7  M5 M2M5 
<U AO1 N%*O1 N2O1 X*%N59	X*AO1 
O $AO1 *O.+O1 ?U X*W.	X*7	M/ M*&L?	M*L	M*$U (X*M	X*M'#X**M//U 2M5 5-N""U %N/*	O1 5N>:X* O+!O$"O+'O1 *O++O1 1
U;T?U BT?$R'%T?*U 0T?	S	T?S&	"T?9U =X*T3*	X*3T<8X*?UU W*W$ -W5%WV.%	W.V7	3W
W$ WW$ W!X*$X'>X	X'X$ X''X*c                >	  K   t         j                  t         j                  z  }| j                  }| j                  j
                  }| j                  j                  }	 	  |        d{   \  }}||fg}|t         j                  z  sdt        |      | j                  k  rL	  |       \  }}|j                  ||f       |t         j                  z  rn	 t        |      | j                  k  rL	 | j                  ri }	|D ].  \  }}||z  r|	j                         D ]y  \  }
} |dj                  |      |
       d{   r'  t        t        |            D ]  }| j                  j!                           	 | j"                  s| j%                          yy |	j'                           |||       d{   r t        t        |            D ]  }| j                  j!                           	 | j"                  s| j%                          yy|	j)                  |g       j                  |       1 |	j                         D ]x  \  }
} |dj                  |      |
       d{   r' t        t        |            D ]  }| j                  j!                           	 | j"                  s| j%                          yy nn|D ]i  \  }} |||       d{   r t        t        |            D ]  }| j                  j!                           	 | j"                  s| j%                          yy t        t        |            D ]  }| j                  j!                           	 |d   d   t         j                  z  rn	 | j"                  s| j%                          yy7 1# t        j                  $ r Y w xY w7 z7 7 [7 # t        t        |            D ]  }| j                  j!                           w xY w# t        j*                  $ r Y t,        $ rb}| j"                  sLt/        t        j0                        5  | j2                  j5                  |df       ddd       n# 1 sw Y   nxY wY d}~d}~ww xY w# | j"                  s| j%                          w w xY ww)a(  
        The high-level send manager. It efficiently gathers pending messages
        from the send queue and orchestrates their transmission.

        This method runs a continuous loop that consumes messages from the
        `_send_queue`. To improve performance and reduce system call overhead,
        it implements an adaptive batching strategy. It greedily gathers
        multiple pending messages from the queue and then coalesces the
        payloads of messages that share the same flags (e.g., all text frames)
        into a single, larger payload, ONLY if `coalesce_frames=True` and the
        frame is not a CONTROL frame, as the spec requires them to be whole.

        It will batch as many as possible, then iterate over the batch and send
        the frames, one at a time. This batching and coalescing significantly
        improves throughput for high volumes of small messages where the message
        boundaries do not matter. The final, consolidated payloads are then passed
        to the `_send_payload` method for transmission.
        NrK   r:  r   r   )r   r   r  _send_payloadr"  r   
get_nowaitrx   r#  r   r<  
QueueEmptyr$  itemsr   range	task_donerg   r   r  
setdefaultr  r|   r   rh  r!  rg  )rS   control_frame_flagssend_payload	queue_getqueue_get_nowaitr   r   batchr}   data_to_coalesceframe_grouppayloadsr   r~   s                 rL   rW  zAsyncWebSocket._write_loop  sS    & $.#3#3joo#E))$$((	++66B	!'0{!2 "5)*z///e*t'@'@@"-=-?NGU!LL'5)9:$z'7'77 %  8	 e*t'@'@@ 5,,CE(.3 WNGU$'::=M=S=S=U !/$9K1=(+(:K2& ,& ,& )/( #3u:. 5((2245" ;;  S!/
 !1 6 6 8-9'5-I'I'I$*  #3u:. 5((2245" ;;  ? !1 ; ;E2 F M Mg VW  6F5K5K5M '1K)5chhx6H+)V#V#V & #3u:. 5((2245" ;;  9'
 /4 'NGU)5gu)E#E#E & #3u:. 5((2245" ;;  /' #3u:. 5((2245 9Q<*"2"22i h  ;;   "3  '11 "!",& (J $W
 $F
 #3u:. 5((2245 %% 	 	;;;g//0 ;''22Aq6:; ; ;	; ;;  s_  ARO9 (N)7O9 !0N O9 -AO <N6=O O 3O9 8RO 3N94O 9O :3O9 .RAO !N<"O 'O (3O9 R:O N?O O 3O9 R)O *AO9 :Q; ;RO9 N3/O9 2N33O9 6O 9O <O ?O 5O66O9 9Q8Q; Q8%Q3;Q"	Q3"Q+	'Q3.Q; 3Q88Q; ;RRc           	       K   | j                   j                  }| j                  j                  }| j                  }t        |      }d}d}|j                         }	|t        |      k  r|| j                  z  dk(  s |j                         |	z
  | j                  kD  r-t        j                  d       d{    |j                         }		 |||| j                  z    }
 ||
|      }|dk(  rEt        t        j                        5   |t        dt         j"                        df       ddd       y||z  }|dz  }|t        |      k  ry7 # 1 sw Y   yxY w# t$        $ rt}|j&                  t         j(                  k7  r>t        t        j                        5   ||df       ddd       n# 1 sw Y   nxY wY d}~y|j+                         }	 |j-                  | j.                  |j0                  d       nn# t2        $ rb}t        t        j                        5   |t        d| t         j4                        df       ddd       n# 1 sw Y   nxY wY d}~Y d}~yd}~ww xY w	 | d{  7   | j.                  dk7  rL|j7                  | j.                         n0# | j.                  dk7  r|j7                  | j.                         w w xY wY d}~d}~ww xY ww)	at  
        The low-level I/O Handler. It transmits a single payload, handling
        fragmentation, backpressure (EAGAIN), and cooperative multitasking.
        Returns False on a non-recoverable error.

        Args:
            payload: The complete byte payload to be sent.
            flags: The `CurlWsFlag` indicating the frame type (e.g., `TEXT`, `BINARY`).
        r   Nzws_send returned 0 bytesFr   zadd_writer failed: r:  T)rb   r   r!  rg  rC  rf  r  rx   r(  r&  r<  r  r,  r   rh  rN   r   
SEND_ERRORr   rU   r   r  
add_writerr  r  r|   r   remove_writer)rS   r   r   curl_ws_sendr  rC  viewr   	write_opsr  r   r   r~   write_futurer  s                  rL   r  zAsyncWebSocket._send_payload  s     zz))..99yy'"	 IIK
s4y D,,,2		j($$7% mmA&&&!YY[
/:Vft/H/H&HI%eU3Q;!'"3"34 	( .$>$-$8$8!" !"	 !& Q	1 s4y p g '	 !  :66Y__,!'"3"34 1(!Q01 1 1   $113!OODMM<3J3JDQ  !!'"3"34 	( .&9#$?$-$E$E!" !"	 	 	 !5!:&&&}}***4==9 }}***4==9 +9:s  B0K2E3K9E #E	$E ,K-
E 7KK	EE KE 
K6KF) 	K)F2	.K5K:K'G32K3	I<I&I;	II	IKKIK"J'I*(J-+K-KKKKKc                d  K   | j                   r?| j                   j                         r%| j                  j                         st	        d      	 t        j                  | j                  j                         |       d{    y7 # t
        j                  $ r}t        d      |d}~ww xY ww)a  Waits until all items in the send queue have been processed.

        This ensures that all messages passed to `send()` have been handed off to the
        underlying socket for transmission. It does not guarantee that the data has
        been received by the remote peer.

        Args:
            timeout (Optional[float], optional): The maximum number of seconds to wait
            for the queue to drain.

        Raises:
            WebSocketTimeout:  If the send queue is not fully processed within the
            specified ``timeout`` period.
            WebSocketError: If the writer task has already terminated while unsent
            messages remain in the queue.
        z6Cannot flush, writer task has terminated unexpectedly.rZ  Nz*Timed out waiting for send queue to flush.)
r  rG  r"  r\  rN   r<  r]  r   r^  r^   )rS   r   r~   s      rL   rs  zAsyncWebSocket.flush=  s     $   %%'$$**, H 	X""4#3#3#8#8#:GLLL## 	X"#OPVWW	Xs<   AB02B	 BB	 B0B	 	B-B((B--B0c                D  K   t               }d}	 | j                  | j                  fD ]6  }	 |r1|j                         s!|j	                          |j                  |       8 |rTt        t        j                        5  t        j                  t        j                  |ddi|       d{    ddd       | j                  j                         sP	 | j                  j                          | j                  j!                          | j                  j                         sP| j&                  dk7  rzt        t(              5  | j*                  j-                  | j&                         ddd       t        t(              5  | j*                  j/                  | j&                         ddd       d| _        t0        | e          | j4                  r1| j4                  j6                  s| j4                  j9                  d       | j:                  j                          y# t        j                  t        f$ r Y w xY w7 # 1 sw Y   xY w# t        j"                  t$        f$ r Y Bw xY w# 1 sw Y   xY w# 1 sw Y   xY w# | j:                  j                          w xY ww)z)Utility method for connection terminationr-  return_exceptionsTrZ  Nr:  )r~  r  r  rG  canceladdr<  r  RuntimeErrorr   r^  r]  gatherr"  r\  r  r  r  
ValueErrorr  r|   rC  r  r  rQ   r   r  r|  r}  r+  )rS   tasks_to_cancelmax_timeoutio_taskrV   s       rL   rx  z AsyncWebSocket._terminate_helper\  s    365*	) OOT-=-=> w||~('++G4	 g223 !**P4P +   &&,,.$$//1$$..0 &&,,. }}"i( ;II++DMM:;i( ;II++DMM:; DM G||DLL$8$8&&t, ""&&(G  ..=    **J7 
; ;; ; ""&&(s   J J 3H J =.H;+H8,H;0"J 4I J "J  &I(&J =&I5#AJ =J H51J 4H55J 8H;;I J I%!J $I%%J (I2-J 5I>:J JJ c                X  K   	 | j                  |      \  | _        | _        | j
                  rB| j                  s6| j                  | j                  xs t        j                         d{    y| j                          y# t        $ r}|j                  | _        Y d}~~d}~ww xY w7 =w)z<Unpack and handle the closing frame, then initiate shutdown.N)r   rd   re   rN   rU   rc   rg   r   r2   r8   r   )rS   rT   r~   s      rL   r  z"AsyncWebSocket._handle_close_frame  s     	&373K3KG3T0Dd0 >>$++**T--?@@@ NN  	& vvD	& As:   B*B AB**B(+B*	B%
B B* B%%B*)r  r*   ri   r   rc   r   rf   r   r2  r   r3  r   r4  r   r5  r   r%  r   r6  floatr7  r   r8  r   r   r  )r   zasyncio.AbstractEventLoop)r   r   )r   r   )r   r  )r   r"   r  )r   Optional[float]r   ztuple[Optional[bytes], int])r   r  r   rW   )r	   z Callable[[Union[str, bytes]], T]r   r  r   r,   )r   z(Union[str, bytes, bytearray, memoryview]r   r   )r   r   r   r  )r   rW   r   r  )r   r   r   r  r   r  r  )rU   r   rT   r   r   r  r   r  )r   r   r   r   r   r   rP   )r   r  r   r  )rT   r   r   r  )*r4   r5   r6   r7   r   r,  __annotations__r.  r/  rR   r   rC  r3  rH  rL  rN  rQ  rY  r   r   r	   r   r   r   r   r   r   r  r   r  r  r2   r8   r   r   rV  rW  r  rs  rx  r  rX   rY   s   @rL   r  r  N  s9   I. +0-/'(}(),, ""#& %$) % %L'L' L'
 L' L' L' L' !L' L' "L' L' L' L' 
L'\   ( (B&

< -1")"	$"H <@ & 38#'	 0 !	
 
: '--.99.9 .9`;;9 >C33&:3	39 &..3QT%S%S38%SIN%S	%SN1@BMHZ!xM^X>/)brK   r  )R
__future__r   r<  rr   r>  r   collections.abcr   
contextlibr   enumr   	functoolsr   jsonr   r	   r
   typingr   r   r   r   r   r   r   aior   r   constr   r   r   r   ri   r   r   utilsr   
exceptionsr   r   modelsr   r    r!   typing_extensionsr"   r#   r$   r   r%   r   r&   r   r'   r(   r)   r  r*   r+   r,   r   	ON_DATA_TrW   ON_MESSAGE_T
ON_ERROR_T	ON_OPEN_Tr   
ON_CLOSE_Ttupler|   RECV_QUEUE_ITEMSEND_QUEUE_ITEMr2   rN   r[   r^   r`   r  r-   r  rJ   rK   rL   <module>r     s   "     $      R R R / < < " # .  ,&'"$$OO0A+uk:D@AI[%s
*;<dBCL;	2D89J+,-I;S1478JE%"23S89OE5S#99:O 	*-' .(Y ('nm ')~w )A AH FG l l^J] JrK   