K if*ddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z ddlmZddlmZmZmZddlmZmZmZmZddlmZmZmZmZmZdd lm Z m!Z!dd l"m#Z#m$Z$m%Z%m&Z&m'Z'dd lm(Z(m)Z)m*Z*d d l+m,Z,d dl-m.Z.dgZ/GddZ0y)) annotationsN)IterableIteratorMapping) TracebackType)AnyLiteraloverload)ConcurrencyErrorConnectionClosedConnectionClosedOK ProtocolError) DATA_OPCODES BytesLike CloseCodeFrameOpcode)RequestResponse)CLOSEDOPENEventProtocolState)Data LoggerLike Subprotocol) Assembler)Deadline ConnectioncneZdZdZdZddddd d,dZed-dZed-d Zed.d Z ed/d Z ed0d Z ed1d Z d2dZ d3dZd4dZed5dZed6dZed7d5dZe d7 d6dZe d8 d9dZd8d9dZed:dZed;dZed7ddZ d? d@dZdAdBd ZdCd!ZdDd"ZdEd#ZdEd$ZdEd%ZdEd&Zej@e!d' dFd(Z"dEd)Z#dGd*Z$dEd+Z%y)Hr"a? :mod:`threading` implementation of a WebSocket connection. :class:`Connection` provides APIs shared between WebSocket servers and clients. You shouldn't use it directly. Instead, use :class:`~websockets.sync.client.ClientConnection` or :class:`~websockets.sync.server.ServerConnection`. i ) ping_interval ping_timeout close_timeout max_queuec||_||_||_||_||_t |t s||df}||_tj|jjd|i|j_ |jj|_ |jj|_ |jj|_ d|_ d|_ tj |_tj |_t'|j|j$j(|j$j*d|_d|_d|_i|_d|_ d|_d|_tj:|j<d|_|j>jAy)N websocket)pauseresumeFrTtargetdaemon)!socketprotocolr'r(r) isinstanceintr*logging LoggerAdapterloggeriddebugrequestresponse threadingLockprotocol_mutexrecv_flow_controlr acquirerelease recv_messagesclose_deadlinesend_in_progress pong_waiterslatencykeepalive_threadrecv_excThread recv_eventsrecv_events_threadstart)selfr2r3r'r(r)r*s `/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/websockets/sync/connection.py__init__zConnection.__init__/s   *(* i %):"D)I" '44 MM $    "]]--B"&--"6"6 )]](( (, ()- )(nn."+!1' ^^((00))11 04!&OQ  :>/3 #,"2"2###  %%'c6|jjS)z Local address of the connection. For IPv4 connections, this is a ``(host, port)`` tuple. The format of the address depends on the address family. See :meth:`~socket.socket.getsockname`. )r2 getsocknamerNs rO local_addresszConnection.local_address{{&&((rQc6|jjS)z Remote address of the connection. For IPv4 connections, this is a ``(host, port)`` tuple. The format of the address depends on the address family. See :meth:`~socket.socket.getpeername`. )r2 getpeernamerTs rOremote_addresszConnection.remote_addressrVrQc.|jjS)aI State of the WebSocket connection, defined in :rfc:`6455`. This attribute is provided for completeness. Typical applications shouldn't check its value. Instead, they should call :meth:`~recv` or :meth:`send` and handle :exc:`~websockets.exceptions.ConnectionClosed` exceptions. )r3staterTs rOr[zConnection.states}}"""rQc.|jjS)z~ Subprotocol negotiated during the opening handshake. :obj:`None` if no subprotocol was negotiated. )r3 subprotocolrTs rOr]zConnection.subprotocols}}(((rQc.|jjSa) State of the WebSocket connection, defined in :rfc:`6455`. This attribute is provided for completeness. Typical applications shouldn't check its value. Instead, they should inspect attributes of :exc:`~websockets.exceptions.ConnectionClosed` exceptions. )r3 close_coderTs rOr`zConnection.close_codes}}'''rQc.|jjSr_)r3 close_reasonrTs rOrbzConnection.close_reasons}})))rQc|SNrTs rO __enter__zConnection.__enter__s rQch||jy|jtjyrd)closerINTERNAL_ERROR)rNexc_type exc_value tracebacks rO__exit__zConnection.__exit__s%   JJL JJy// 0rQc#RK |j#t$rYywxYww)aC Iterate on incoming messages. The iterator calls :meth:`recv` and yields messages in an infinite loop. It exits when the connection is closed normally. It raises a :exc:`~websockets.exceptions.ConnectionClosedError` exception after a protocol error or a network failure. N)recvrrTs rO__iter__zConnection.__iter__s0 iik!!   s' $'$'cyrdrerNtimeoutdecodes rOrozConnection.recvILrQcyrdrerrs rOrozConnection.recvLOrQNcyrdrerrs rOrozConnection.recvsSVrQcyrdrerrs rOrozConnection.recvsrQcyrdrerrs rOrozConnection.recvsrQc |jj||S#t$rYnt$r tddt$rs}|j 5|j jtj|jd|jdddn #1swYnxYwYd}~nd}~wwxYw|jj|j j|j)a Receive the next message. When the connection is closed, :meth:`recv` raises :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it raises :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal closure and :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol error or a network failure. This is how you detect the end of the message stream. If ``timeout`` is :obj:`None`, block until a message is received. If ``timeout`` is set, wait up to ``timeout`` seconds for a message to be received and return it, else raise :exc:`TimeoutError`. If ``timeout`` is ``0`` or negative, check if a message has been received already and return it, else raise :exc:`TimeoutError`. If the message is fragmented, wait until all fragments are received, reassemble them, and return the whole message. Args: timeout: Timeout for receiving a message in seconds. decode: Set this flag to override the default behavior of returning :class:`str` or :class:`bytes`. See below for details. Returns: A string (:class:`str`) for a Text_ frame or a bytestring (:class:`bytes`) for a Binary_ frame. .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 You may override this behavior with the ``decode`` argument: * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and return a bytestring (:class:`bytes`). This improves performance when decoding isn't needed, for example if the message contains JSON and you're using a JSON library that expects a bytestring. * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and return a string (:class:`str`). This may be useful for servers that send binary frames instead of text frames. Raises: ConnectionClosed: When the connection is closed. ConcurrencyError: If two threads call :meth:`recv` or :meth:`recv_streaming` concurrently. zOcannot call recv while another thread is already running recv or recv_streamingN at position )rCgetEOFErrorr UnicodeDecodeError send_contextr3failr INVALID_DATAreasonrMrLjoin close_excrI)rNrsrtexcs rOrozConnection.recv s` %%))'6: :   "< " ""$  ""**zzl- {;     $$&mm%%4==8s3 B8B8B3AB" B3"B+ 'B33B8cyrdrerNrts rOrecv_streamingzConnection.recv_streamingRsFIrQcyrdrers rOrzConnection.recv_streamingUrurQcyrdrers rOrzConnection.recv_streamingXrwrQc#K |jj|Ed{y7#t$rYnt$r tddt$rs}|j 5|j jtj|jd|jdddn #1swYnxYwYd}~nd}~wwxYw|jj|j j|jw)a Receive the next message frame by frame. This method is designed for receiving fragmented messages. It returns an iterator that yields each fragment as it is received. This iterator must be fully consumed. Else, future calls to :meth:`recv` or :meth:`recv_streaming` will raise :exc:`~websockets.exceptions.ConcurrencyError`, making the connection unusable. :meth:`recv_streaming` raises the same exceptions as :meth:`recv`. Args: decode: Set this flag to override the default behavior of returning :class:`str` or :class:`bytes`. See below for details. Returns: An iterator of strings (:class:`str`) for a Text_ frame or bytestrings (:class:`bytes`) for a Binary_ frame. .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 You may override this behavior with the ``decode`` argument: * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and return bytestrings (:class:`bytes`). This may be useful to optimize performance when decoding isn't needed. * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and return strings (:class:`str`). This is useful for servers that send binary frames instead of text frames. Raises: ConnectionClosed: When the connection is closed. ConcurrencyError: If two threads call :meth:`recv` or :meth:`recv_streaming` concurrently. NzYcannot call recv_streaming while another thread is already running recv or recv_streamingr|)rCget_iterr~r rrr3rrrrrMrLrrrI)rNrtrs rOrzConnection.recv_streaming[sN ))226: : :  ;   "< " ""$  ""**zzl- {;     $$&mm%%4==8sZD*(*D* CDCB?!AB.% B?.B7 3B?:D?C>Dct|tr|j5|jr t d|dur*|j j |jn)|j j|jdddyt|trl|j5|jr t d|dur|j j|n|j j |dddyt|tr tdt|tr]t|} t|} t|tr|j5|jr t dd|_|dur,|j j |jdn+|j j|jddddd}nt|try|j5|jr t dd|_|dur|j j|dn|j j |ddddd}n td|D]}t|trU|rS|j5|jsJ|j j!|jddddht|trG|sE|j5|jsJ|j j!|ddddtd|j5|j j!d dd|_dddyytd #1swYyxYw#1swYyxYw#t$rYywxYw#1swYxYw#1swYcxYw#1swY`xYw#1swYmxYw#1swYpxYw#t$rt"$rQ|j5|j j%t&j(d ddd#1swYxYwwxYw) a Send a message. A string (:class:`str`) is sent as a Text_ frame. A bytestring or bytes-like object (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) is sent as a Binary_ frame. .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 You may override this behavior with the ``text`` argument: * Set ``text=True`` to send a bytestring or bytes-like object (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) as a Text_ frame. This improves performance when the message is already UTF-8 encoded, for example if the message contains JSON and you're using a JSON library that produces a bytestring. * Set ``text=False`` to send a string (:class:`str`) in a Binary_ frame. This may be useful for servers that expect binary frames instead of text frames. :meth:`send` also accepts an iterable of strings, bytestrings, or bytes-like objects to enable fragmentation_. Each item is treated as a message fragment and sent in its own frame. All items must be of the same type, or else :meth:`send` will raise a :exc:`TypeError` and the connection will be closed. .. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4 :meth:`send` rejects dict-like objects because this is often an error. (If you really want to send the keys of a dict-like object as fragments, call its :meth:`~dict.keys` method and pass the result to :meth:`send`.) When the connection is closed, :meth:`send` raises :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it raises :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal connection closure and :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol error or a network failure. Args: message: Message to send. Raises: ConnectionClosed: When the connection is closed. ConcurrencyError: If the connection is sending a fragmented message. TypeError: If ``message`` doesn't have a supported type. z=cannot call send while another thread is already running sendFNTzdata is a dict-like object)finz'data iterable must contain bytes or strz(data iterable must contain uniform typesrQzerror in fragmented messagez$data must be str, bytes, or iterable)r4strrrEr r3 send_binaryencode send_textrr TypeErrorriternext StopIterationsend_continuation Exceptionrrri)rNmessagetextchunkschunkrs rOsendzConnection.sends)r gs #""$ >((*W5=MM--gnn.>?MM++GNN,<= > > +""$ 7((*W4<MM++G4MM--g6 7 7 )89 9 *']F V > eS)**, O00"2!:#15-5= MM55elln%5P MM33ELLN3N O"Fy1**, H00"2!:#15-4< MM33Eu3E MM55e5G H#F#$MNN$ TE!%-&!..0W#'#8#88#8 MM;;ELLNPU;VWW$E95f!..0N#'#8#88#8 MM;;Eu;MNN((RSS T&&(2MM33CT3B,1D)22(BC CI > > 7 7*!   O O H H$WWNN22$  &&(MM&&!005    sA/N)9AN5 O P9A:O3+PAO<=P9:O*3+P,O7 %P/%PP)N25N> O  O OPO'"P*O4 /P7P <PP  P"Q32+Q& Q3&Q/ +Q3c |j5|jr+|jjtj dn|jj ||dddy#1swYyxYw#t$rYywxYw)a Perform the closing handshake. :meth:`close` waits for the other end to complete the handshake, for the TCP connection to terminate, and for all incoming messages to be read with :meth:`recv`. :meth:`close` is idempotent: it doesn't do anything once the connection is closed. Args: code: WebSocket close code. reason: WebSocket close reason. zclose during fragmented messageN)rrEr3rrri send_closer )rNcoders rOrhzConnection.close9s|  ""$ ;((MM&&!009 MM,,T6: ; ; ;    s/A;AA/&A;/A84A;8A;; BBcTt|tr t|}n.t|tr|j }n | t d|j 5||jvr td|||jvr;tjdtjd}|,||jvr;tj}|tj |f|j|<|j"j%||cdddS#1swYyxYw)a8 Send a Ping_. .. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 A ping may serve as a keepalive or as a check that the remote endpoint received all messages up to this point Args: data: Payload of the ping. A :class:`str` will be encoded to UTF-8. If ``data`` is :obj:`None`, the payload is four random bytes. ack_on_close: when this option is :obj:`True`, the event will also be set when the connection is closed. While this avoids getting stuck waiting for a pong that will never arrive, it requires checking that the state of the connection is still ``OPEN`` to confirm that a pong was received, rather than the connection being closed. Returns: An event that will be set when the corresponding pong is received. You can ignore it if you don't intend to wait. :: pong_event = ws.ping() pong_event.wait() # only if you want to wait for the pong Raises: ConnectionClosed: When the connection is closed. ConcurrencyError: If another ping was sent with the same data and the corresponding pong wasn't received yet. Ndata must be str or bytes-likez-already waiting for a pong with the same dataz!I )r4rbytesrrrrrFr structpackrandom getrandbitsr=rtime monotonicr3 send_ping)rNdata ack_on_close pong_waiters rOpingzConnection.pingYsL dI &;D c ";;=D  <= =    t(((&'VWW,$$*;*;";{{4););B)?@,$$*;*;";$//+K'2DNN4Dl&SD  d # MM # #D )   sAD1DADD'ct|tr t|}n,t|tr|j }n t d|j 5|jj|dddy#1swYyxYw)ab Send a Pong_. .. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 An unsolicited pong may serve as a unidirectional heartbeat. Args: data: Payload of the pong. A :class:`str` will be encoded to UTF-8. Raises: ConnectionClosed: When the connection is closed. rN) r4rrrrrrr3 send_pongrNrs rOpongzConnection.pongsk dI &;D c ";;=D<= =     * MM # #D ) * * *s A>>Bct|tsJ|jtvr|jj ||jt jur%|jt|jyy)zx Process one incoming event. This method is overridden in subclasses to handle the handshake. N) r4ropcoderrCputrPONGacknowledge_pingsrr)rNevents rO process_eventzConnection.process_events`%''' <<< '    " "5 ) <<6;; &  " "5#4 5 'rQc|j5||jvr dddytj}d}g}|jj D];\}\}}}|j ||j ||k(s1||z |_n td|D]}|j|= dddy#1swYyxYw)z; Acknowledge pings when receiving a pong. Nz!solicited pong not found in pings) r?rFrritemsappendsetrGAssertionError)rNrpong_timestampping_idping_idsrping_timestamp _ack_on_closes rOrzConnection.acknowledge_pingss   /4,,, / / "^^-NGH ""((* J(!d?#1N#BDL J%%HII$ /%%g. /3 / / /sB?A"B? ,B??Cc|jjtusJ|jj D]\}}}|s |j |jj y)zK Acknowledge pending pings when the connection is closed. N)r3r[rrFvaluesrclear)rNr_ping_timestamprs rOacknowledge_pending_pingsz$Connection.acknowledge_pending_pingssb }}""f,,,:>:K:K:R:R:T " 6K,! " !rQc6|jJ |jj|j|jz |jj sy |j d}|jr|jjd|j|j|jr(|jr|jjdnk|jr|jjd|j5|jjtjddddyC#t $rYywxYw#1swYxYw#t $r |jj#dd YywxYw) zT Send a Ping frame and wait for a Pong frame at regular intervals. NT)rz% sent keepalive pingz% received keepalive pongz&- timed out waiting for keepalive pongzkeepalive ping timeoutzkeepalive ping failedexc_info)r'rLrrGis_aliverr r:r8r(waitrr3rrrirerror)rNrs rO keepalivezConnection.keepalivese !!--- F'',,T-?-?$,,-NO..779"&)))">K::KK%%&=>$$0"''(9(9::: KK--.IJ:: KK--.VW!..0 MM.. ) 8 8 8 9(  F KK  5  E FsUA E/E1B-E/+E# E/E/ E E/E  E/#E,(E//&FFc|jAtj|jd|_|jj yy)zS Run :meth:`keepalive` in a thread, unless keepalive is disabled. NTr/)r'r=rJrrHrMrTs rOstart_keepalivezConnection.start_keepalivesF    )$-$4$4~~%D !  ! ! ' ' ) *rQcR |j5|j3|jj|jj ddd|jj |j }|dk(rn|j5|jj||jj} |j|jj!r&|jt#|j$|_dddD]}|j'|5|j5|jj)|jj}|jdddD]}|j'| |j-y#1swYmxYw#t$rf}|jr|jjdd|j5|j|dddn #1swYnxYwYd}~d}~wwxYw#t$rM}|jr|jjdd|j|Yd}~dddSd}~wwxYw#1swYxYw#1swYxYw#t$r[}|jj+dd|j5|j|dddn #1swYnxYwYd}~bd}~wwxYw#|j-wxYw)z Read incoming data from the socket and process events. Run this method in a thread as long as the connection is alive. ``recv_events()`` exits immediately when the ``self.socket`` is closed. TNz! error while receiving datarrQ! error while sending dataunexpected internal error)r@rDr2 settimeoutrsro recv_bufsizerr:r8r? set_recv_excr3 receive_dataevents_received send_dataclose_expectedr!r)r receive_eofr close_socket)rNrreventsrs rOrKzConnection.recv_eventss^ //R..: KK2243F3F3N3N3PQR ;;++D,=,=>D3;((OMM..t4"]]::+>+F+F+HI ##D)KK((8 s)C CCcd|jjsJ|j||_yy)zf Set recv_exc, if not set yet. This method requires holding protocol_mutex. N)r?rrI)rNrs rOrzConnection.set_recv_exc s2""))+++ == DM !rQc |jjtj|jj |j 5|j j|j jtusJ ddd|jj |jy#t$rYwxYw#1swYCxYw)z Shutdown and close socket. Close message assembler. Calling close_socket() guarantees that recv_events() terminates. Indeed, recv_events() may block only on socket.recv() or on recv_messages.put(). N) r2r SHUT_RDWRrrhr?r3rr[rrCrrTs rOrzConnection.close_sockets  KK !1!1 2   1 MM % % '==&&&0 00 1   " &&(     1 1s)B>9C > C  C  C)r2z socket.socketr3rr' float | Noner(rr)rr*z*int | None | tuple[int | None, int | None]returnNone)rr)rr)rzSubprotocol | None)rz int | None)rz str | None)rr")rjztype[BaseException] | NonerkBaseException | NonerlzTracebackType | Nonerr)rIterator[Data])rsrrt Literal[True]rr)rsrrtLiteral[False]rrrd)NN)rsrrt bool | Nonerr)rtrrz Iterator[str])rtrrzIterator[bytes])rtrrr)rzData | Iterable[Data]rrrr)rr5rrrr)NF)rz Data | Nonerboolrzthreading.Event)rQ)rrrr)rrrr)rrrr)rr)rrrzIterator[None])rrrr)&__name__ __module__ __qualname____doc__rrPpropertyrUrYr[r]r`rbrfrmrpr rorrrNORMAL_CLOSURErhrrrrrrrrK contextlibcontextmanagerrrrrrrerQrOr"r" s L')%'&(@BY(Y(Y( $ Y( # Y($Y(>Y( Y(z ) ) ) ) # #)) ( ( * * 1, 1( 1( 1  1(LL OO VV &*#7E BF#4? D9LII LL OO<9B!^D&^D^D  ^D@!* 8 8D!"999  9v*6 6/B "%FN *g R!%k<k<  k<krsl"  77)) GF&;;22 .P)P)rQ