
    afՖ                         d dl Z d dlZd dlm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mZmZ d dlmZmZ d dlmZmZ d dlmZ d	Zdd
ZddZ G d de          Z G d d	e          ZddZdS )    N)partial)ObservableMixin)	parse_url)ComponentConfigSubscribeOptionsRegisterOptions)SessionNotReadyApplicationError)create_authenticatorIAuthenticator)SERID_TO_SER	Componentc                 >   |r ||            n$t          | t                    st          d          t          | t                    rTd| vrt          d          | d         dvr(t          d                    | d                             |                                 D ](}|dvr"t          d                    |                    )| d         dk    rXd	D ](}|| vr"t          d
                    |                    )dD ](}|| v r"t          d                    |                    )dS | d         dk    rXdD ](}|| vr"t          d                    |                    )dD ](}|| v r"t          d                    |                    )dS J d            dS )z9
    Check a WAMP connecting endpoint configuration.
    z'endpoint' must be a dicttypez)'type' required in endpoint configuration)tcpunixzinvalid type "{}" in endpoint)r   hostportpathtlstimeoutversionz*Invalid key '{}' in endpoint configurationr   r   r   z&'{}' required in 'tcp' endpoint config)r   z''{}' not valid in 'tcp' endpoint configr   z('{}' required for 'unix' endpoint config)r   r   r   z('{}' not valid in 'unix' endpoint configFshould not arrive hereN)
isinstancedict
ValueErrorformatkeys)endpointcheck_native_endpointks      I/var/www/html/env/lib/python3.11/site-packages/autobahn/wamp/component.py_validate_endpointr$   1   sP     
h''''$'' 
'
 
 	
 (D!! &3 !!HIIIF?22<CCHVDTUUVVV 	 	AUUU @GGJJ   V
 Fu$$%  H$$$@GGJJ   %   ==$AHHKK   ! 
 f''  H$$$BII!LL   % -  ==$BII!LL   !  32225M&3 &3    c                  	   t          |          t          k    r/t          d                    t          |                              g d}|                                D ](}||vr"t          d                    |                    )d}d|v r;|d         dvr(t          d                    |d                             |d         }nd|d<   d|v r|dk    rt          d	          |                    dd
          }|h|                                D ](}|dvr"t          d                    |                    )dD ](}||vr"t          d                    |                    )t                      }d|v rL|d         }t          |t                    s/t          d                    t          |                              |                    d          }|dk    r]dD ](}	|	|vr"t          d                    |	                    )d|vr$t          |d                   \  }
}}}}}d|||
d}n|d         }t          ||           d|v rt          d          d|v rt          |d         t          t          f          st          d          t          d |d         D                       st          d          t          j                    }|d         D ]F}||vr@t          d                    |d                    d |D                                           G|                    ddd g          }n|d!k    rd|vr|d                             d"          rt!          |d                   \  }}}nF|d                             d#          rt          |d                   \  }}}}}}nt#                      |d$k    rd$|d%}nd||d&}n|d         }d|v rt          d'          |t          d(          d|v r;t          |d         t$          t$          f          st          d)          |d         g}ndg}n
J d+            i }d,D ]}	|	|v r||	         ||	<   t'          | f||                    dd
          |||||d-|S ).a   
    Internal helper to insert defaults and create _Transport instances.

    :param transport: a (possibly valid) transport configuration
    :type transport: dict

    :returns: a _Transport instance

    :raises: ValueError on invalid configuration
    z<invalid type {} for transport configuration - must be a dict)r   urlr    
serializerserializersoptionsmax_retriesmax_retry_delayinitial_retry_delayretry_delay_growthretry_delay_jitterproxyheadersz&'{}' is not a valid configuration item	websocketr   )r2   	rawsocketzInvalid transport type {}r0   z3proxy= only supported for type=websocket transportsNr   z Unknown key '{}' in proxy configzProxy config requires '{}'r*   zoptions must be a dict, not {}r1   )r'   zTransport requires '{}' keyr    r'   r   )r   r   r   r   r(   z5'serializer' is only for rawsocket; use 'serializers'r)   z''serializers' must be a list of stringsc                 F    g | ]}t          |t          t          f          S  )r   str.0ss     r#   
<listcomp>z%_create_transport.<locals>.<listcomp>   s6     7 7 7 q3*--7 7 7r%   z-Invalid serializer '{}' (expected one of: {})z, c                 ,    g | ]}t          |          S r5   )reprr7   s     r#   r:   z%_create_transport.<locals>.<listcomp>   s    &J&J&J1tAww&J&J&Jr%   cborjsonr3   rswsr   )r   r   )r   r   r   z5'serializers' is only for websocket; use 'serializer'z/'headers' not supported for rawsocket transportz'serializer' must be a stringFr   )r+   r,   r-   r.   r/   )kindr'   r    r)   r0   r*   r1   )r   r   r   r   r   getformaTr   parse_ws_urlr$   listtupleallr   join
startswithparse_rs_urlRuntimeErrorr6   
_Transport)index	transportr!   valid_transport_keysr"   rA   r0   r*   r1   key	is_securer   r   resourcer   paramsendpoint_configvalid_serializersserialserializer_configisSecurekws                         r#   _create_transportrZ   j   s    I$W^^_cdm_n_nooppp  
 ^^  (((8??BB   )
 DV$>>>8??	&@QRRSSS '	&) 3 3A
 
 	
 MM'4((E 	 	A((( 6==a@@   ) " 	 	A~~ 077::   
 ffGII&'4(( 	077WFF   mmI&&G{ 	L 	LC)## !>!E!Ec!J!JKKK $ Y&&<HSXIY<Z<Z9ItT8T6 	 OO (
3O0EFFF9$$TUUUI%%i6uFF L !JKKK 7 7&}57 7 7 8 8 L !!JKKK , 1 3 3#M2  !222$GNN" II&J&J8I&J&J&JKK    3 &MM-&&9IJJ			Y&&**400 %'3Ie4D'E'E$$5!,,T22 %?KIV[L\?]?]<$hff"nn$v~~ # # # "  # # (
3OI%%TUUUNOOO9$$i5SzBB B !@AAA!*<!8 9!' 	/...u	B< % %)nBsG
MM%&& %
 
 
 
 
r%   c                   H    e Zd ZdZ	 	 	 	 	 	 	 	 ddZd Zd	 Zd
 Zd Zd Z	dS )rL   z@
    Thin-wrapper for WAMP transports used by a Connection.
    ,        ?皙?Nc                 l   |t                      }|| _        || _        || _        || _        || _        || _        || _        | j        dk    r"t          |          dk    rt          d          || _
        || _        || _        |	| _        |
| _        || _        d| _        |                                  dS )z	
        Nr3      z5'rawsocket' transport requires exactly one serializerF)r   idxr   r'   r    r*   r1   r)   lenr   r+   r,   r-   r.   r/   r0   _permanent_failurereset)selfrb   rA   r'   r    r)   r+   r,   r-   r.   r/   r0   r*   r1   s                 r#   __init__z_Transport.__init__  s     ?ffG	 &9##K(8(8A(=(=G   '.#6 "4"4
 #(

r%   c                 H    d| _         d| _        d| _        | j        | _        dS )zP
        set connection failure rates and retry-delay to initial values
        r   N)connect_attemptsconnect_sucessesconnect_failuresr-   retry_delayrf   s    r#   re   z_Transport.reset5  s-     !" ! !3r%   c                     d| _         dS )z
        Mark this transport as failed, meaning we won't try to connect to
        it any longer (that is: can_reconnect() will always return
        False afer calling this).
        TN)rd   rm   s    r#   failedz_Transport.failed>  s     #'r%   c                 T    | j         rdS | j        dk    rdS | j        | j        dz   k     S )NFr\   Tra   )rd   r+   ri   rm   s    r#   can_reconnectz_Transport.can_reconnectF  s;    " 	5r!!4$t'7!';;;r%   c                 <   | j         dk    rdS | j        dk    r"| j         | j        dz   k    rt          d          | j        | j        z  | _        t          j        | j        | j        | j        z            | _        | j        | j        k    r| j        | _        | j        S )Nr   r\   ra   zmax reconnects reached)	ri   r+   rK   rl   r.   randomnormalvariater/   r,   rm   s    r#   
next_delayz_Transport.next_delayM  s     A%%1##(=AQTUAU(U(U7888#/$2IID%3D4DdFVY]YpFpqqD$"666#'#7 ##r%   c                 x    t          | j        t                    r| j        d         S t          | j                  S )zF
        returns a human-readable description of the endpoint
        r   )r   r    r   r<   rm   s    r#   describe_endpointz_Transport.describe_endpointZ  s5     dmT** 	)=((DM"""r%   )r\   r]   r^   r^   r_   NNN)
__name__
__module____qualname____doc__rg   re   ro   rq   ru   rw   r5   r%   r#   rL   rL     s         
  !$%($'$'& & & &P4 4 4' ' '< < <$ $ $# # # # #r%   rL   c                   r    e Zd ZdZdZ	 ddZddZ	 	 ddZd Zdd	Z	d
 Z
d Zd Zd Zd Zd Zd Zd ZdS )r   z
    A WAMP application component. A component holds configuration for
    (and knows how to create) transports and sessions.
    NFc                 P     t          t                    sJ  fd}|S )a[  
        A decorator as a shortcut for subscribing during on-join

        For example::

            @component.subscribe(
                "some.topic",
                options=SubscribeOptions(match='prefix'),
            )
            def topic(*args, **kw):
                print("some.topic({}, {}): event received".format(args, kw))
        Nc                 F      fd}                     d|            S )Nc                 6    |                                S )N)topicr*   check_types)	subscribe)sessiondetailsr   fnr*   r   s     r#   do_subscriptionz?Component.subscribe.<locals>.decorator.<locals>.do_subscription  s!    ((5'Wb(cccr%   rH   on)r   r   r   r*   rf   r   s   ` r#   	decoratorz&Component.subscribe.<locals>.decorator  sM    d d d d d d d dGGFO,,,Ir%   )r   r   )rf   r   r*   r   r   s   ```` r#   r   zComponent.subscriber  sQ     *W6F"G"GG	 	 	 	 	 	 	 	 r%   c                 P     t          t                    sJ  fd}|S )aZ  
        A decorator as a shortcut for registering during on-join

        For example::

            @component.register(
                "com.example.add",
                options=RegisterOptions(invoke='roundrobin'),
            )
            def add(*args, **kw):
                print("add({}, {}): event received".format(args, kw))
        Nc                 F      fd}                     d|            S )Nc                 6    |                                S )N)	procedurer*   r   )register)r   r   r   r   r*   uris     r#   do_registrationz>Component.register.<locals>.decorator.<locals>.do_registration  s!    ''c7Xc'dddr%   rH   r   )r   r   r   r*   rf   r   s   ` r#   r   z%Component.register.<locals>.decorator  sM    e e e e e e e eGGFO,,,Ir%   )r   r   )rf   r   r*   r   r   s   ```` r#   r   zComponent.register  sP     *Wo"F"FF	 	 	 	 	 	 	 	 r%   realm1c	                    |                      g d           |t          |          st          d          || _        |t          |          st          d          || _        |d}t          |t          t          f          r|}	d|	d}
|
g}nt          |t                    r|g}g | _        t          |          D ]S\  }}
t          |
          t          k    rd|
d}n|
}| j                            t          ||| j                             T|pi | _        |r|| _        || _        || _        d| _        d| _        d| _        d| _        dS )	a  
        :param main: After a transport has been connected and a session
            has been established and joined to a realm, this (async)
            procedure will be run until it finishes -- which signals that
            the component has run to completion. In this case, it usually
            doesn't make sense to use the ``on_*`` kwargs. If you do not
            pass a main() procedure, the session will not be closed
            (unless you arrange for .leave() to be called).

        :type main: callable taking two args ``reactor`` and ``ISession``

        :param transports: Transport configurations for creating
            transports. Each transport can be a WAMP URL, or a dict
            containing the following configuration keys:

                - ``type`` (optional): ``websocket`` (default) or ``rawsocket``
                - ``url``: the router URL
                - ``endpoint`` (optional, derived from URL if not provided):
                    - ``type``: "tcp" or "unix"
                    - ``host``, ``port``: only for TCP
                    - ``path``: only for unix
                    - ``timeout``: in seconds
                    - ``tls``: ``True`` or (under Twisted) an
                      ``twisted.internet.ssl.IOpenSSLClientComponentCreator``
                      instance (such as returned from
                      ``twisted.internet.ssl.optionsForClientTLS``) or
                      ``CertificateOptions`` instance.
                - ``max_retries``: Maximum number of reconnection attempts. Unlimited if set to -1.
                - ``initial_retry_delay``: Initial delay for reconnection attempt in seconds (Default: 1.0s).
                - ``max_retry_delay``: Maximum delay for reconnection attempts in seconds (Default: 60s).
                - ``retry_delay_growth``: The growth factor applied to the retry delay between reconnection attempts (Default 1.5).
                - ``retry_delay_jitter``: A 0-argument callable that introduces nose into the delay. (Default random.random)
                - ``serializer`` (only for raw socket): Specify an accepted serializer (e.g. 'json', 'msgpack', 'cbor', 'ubjson', 'flatbuffers')
                - ``serializers``: Specify list of accepted serializers
                - ``options``: tbd
                - ``proxy``: tbd

        :type transports: None or str or list

        :param realm: the realm to join
        :type realm: str

        :param authentication: configuration of authenticators
        :type authentication: dict

        :param session_factory: if None, ``ApplicationSession`` is
            used, otherwise a callable taking a single ``config`` argument
            that is used to create a new `ApplicationSession` instance.

        :param is_fatal: a callable taking a single argument, an
            ``Exception`` instance. The callable should return ``True`` if
            this error is "fatal", meaning we should not try connecting to
            the current transport again. The default behavior (on None) is
            to always return ``False``
        )startconnectrH   readyleave
disconnectconnectfailureNz%"is_fatal" must be a callable or Nonez""main" must be a callable if givenzws://127.0.0.1:8080/wsr2   )r   r'   F)set_valid_eventscallabler   	_is_fatal_entryr   r6   r   _transports	enumerater   appendrZ   _check_native_endpoint_authenticationsession_factory_realm_extra_delay_f_done_f_session	_stopping)rf   main
transportsconfigrealmextraauthenticationr   is_fatalr'   rN   rb   
_transports                r#   rg   zComponent.__init__  s   r 	  
	
 
	
 
	
 (:(:DEEE!HTNNABBB 1J j3*-- 	&C $ I $JJ 
D)) 	&$J '
33 	 	NCI#%%'$ 


 '
##!#z43NOO   
  .3 	3#2D r%   c                 H    | j         D ]}|                                r dS dS )NTF)r   rq   )rf   rN   s     r#   _can_reconnectzComponent._can_reconnect  s9    ) 	 	I&&(( ttur%   c                    	
  j         5t          j                    fd}t          j         j         ||           S t          j                     _          fd}t          j         j         ||           t	          j         j                  
dg fd 	fd 
fd	                     d           }t          j        |	            j         S )	a  
        This starts the Component, which means it will start connecting
        (and re-connecting) to its configured transports. A Component
        runs until it is "done", which means one of:

        - There was a "main" function defined, and it completed successfully;
        - Something called ``.leave()`` on our session, and we left successfully;
        - ``.stop()`` was called, and completed successfully;
        - none of our transports were able to connect successfully (failure);

        :returns: a Future/Deferred which will resolve (to ``None``) when we are
            "done" or with an error if something went wrong.
        Nc                 2    t          j        |            d S N)txaioresolve)argds    r#   _cbzComponent._start.<locals>._cb;  s    a%%%%%r%   c                     d_         | S )z}
            if the _done_f future is resolved (good or bad), we want to set it
            to None in our class
            N)r   )r   rf   s    r#   _resetz Component._start.<locals>._resetE  s    
  DLJr%   r   c                 H   d _         j        rt          j        j        d            d S j                            dt          j        |                      j                            dt          j	        |                      t          j
        j        |            d S )NzInternal error {msg}msg{tb}tb)r   r   r   r   r   loginfofailure_messagedebugfailure_format_tracebackreject)failrf   s    r#   errorzComponent._start.<locals>.errorU  s     DM~ 	1
 dlD111114%:OPT:U:UVVVv%*H*N*NOOOT\400000r%   c                     d _         	fdfdfd}fd}t          j        j        d                   }t          j        |||           d S )Nc                    j                             dt          j        |                      j                             dt          j        |                      t          | j        t                    r4j                             d| j        	                                           nt          | j        t                    r/j                             dt          j        |                      n                    | j                  r9| j        j        d         d         \  }}}j                             d	|
           n.j                             dt          j        |                      j        d}n                    | j                  }|r4j                             d           d                                          t          j        dd            d S )Nzcomponent failed: {error})r   r   r   z{msg}r   z&Connection failed with OS error: {msg}r   zTLS failure: {reason})reasonzConnection failed: {error}Fz"Error was fatal; failing transport)r   r   r   r   r   r   valuer
   r   error_messageOSErrorr   _is_ssl_errorargsr   ro   
call_later)r   ssl_libssl_func
ssl_reasonr   rf   transport_candidatetransport_checks        r#   handle_connect_errorzGComponent._start.<locals>.attempt_connect.<locals>.handle_connect_errore  s    :%BWX\B]B]^^^v%*H*N*NOOO dj*:;; HNN7
0H0H0J0JNKKKK
G44  HMM"JPUPefjPkPkMllll''
33  59JOA4Fq4I1GXzHNN#::NNNNNHNN4#3D99 #   
 >)$HH#~~dj99H 4HMM"FGGG'*11333 OT:::r%   c                      t          j                                        d j                  }t          j        | fd fd           S )Nr   c                 .    t          j                  S r   r   r   _chain_fr   s    r#   <lambda>zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>      el7D99 r%   c                 .    t          j                  S r   r   r   s    r#   r   zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>  r   r%   )r   create_futurefirer   add_callbacks)r   	handler_fr   rf   s   ` @r#   notify_connect_errorzGComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error  sj    -//
 !II&6djII	#9999999999  
 r%   c                 J     |           }t          j        |d            d S r   )r   r   )r   notify_fr   r   s     r#   connect_errorz@Component._start.<locals>.attempt_connect.<locals>.connect_error  s/    //55#Hd4HIIIIIr%   c                 <    t          j        j        d            d S r   )r   r   r   )xrf   s    r#   session_donez?Component._start.<locals>.attempt_connect.<locals>.session_done  s    dlD11111r%   r   )r   r   	as_future_connect_oncer   )
r   r   r   	connect_fr   r   looprf   r   r   s
       @@r#   attempt_connectz)Component._start.<locals>.attempt_connectb  s     DM. . . . . . .`    J J J J J J2 2 2 2 2 ")!, I 	<GGGGGr%   c                 V   j                             d                                           s^d}j                             |           	 t	          |          # t          $ r%}t          j        j        |           Y d }~d S d }~ww xY w	 t          	          }|	                                r|d<   n*|
                                }j                             d|j        |j        |           t          j        |          _        t          j        j                   d S )NzEntering re-connect loopz:Component failed: Exhausted all transport connect attemptsTr   zZtrying transport {transport_idx} ("{transport_url}") using connect delay {transport_delay})transport_idxtransport_urltransport_delay)r   r   r   r   rK   r   r   r   nextrq   ru   warnrb   r'   sleepr   r   )
r   err_msgerN   delayr   r   rf   r   transport_gens
        r#   r   z)Component._start.<locals>.transport_check  sA   HNN5666&&(( Vg&&&&w///#   Lq111FFFFF //	**,, -6'* ((**EHMMl'm'm %	     "K..DMFFFFFs   A 
B&BBr   )r   r   r   r   	itertoolscycler   r   )rf   r   r   r   start_fr   r   r   r   r   r   s   ``   @@@@@@r#   _startzComponent._start&  sx   $ <##%%A& & & & & c3777H *,,	 	 	 	 	 	DL&&999 "(899  !c	1 	1 	1 	1 	1L	H L	H L	H L	H L	H L	H L	H L	H\	G 	G 	G 	G 	G 	G 	G 	G 	G@ ))GT400G_e<<<|r%   c                 f   d| _         | j        r2| j                                        r| j                                        S | j        r$t          j        t
          j        | j                  S t          j        | j	                  st          j
        | j	        d            t          j        d           S )NT)r   r   is_attachedr   r   r   r   cancel	is_calledr   r   create_future_successrm   s    r#   stopzComponent.stop  s    = 	@T]6688 	@=&&(((] 	@ ?5<???
 t|,, 	.M$,---*4000r%   c                 >     j                             dj                                                   t	          j                     fd}xj        dz  c_        t	          j         j        |          }fd}t	          j	        |d |           S )NzWconnecting once using transport type "{transport_type}" over endpoint "{endpoint_desc}")transport_typeendpoint_descc                     t          j        j                  } 	                     |           x_        }j                                        D ]R\  }}t          |t                    r|	                    |           0t          |fi |}|	                    |           S	 |_        
fd}|                    d|           
fd}j        |                    d|           
fd}|                    d|           |S # t          $ r/}t          j        |          }	t          j        
|	            d }~ww xY w)Nc                 .   j                             d|           t          j                  sc|j        dv rt          j        d            d S t          j        t          |j        |j                            }t          j	        |           d S d S )Nz"session leaving '{details.reason}'r   )zwamp.close.normalzwamp.close.goodbye_and_out)
r   r   r   r  r   r   create_failurer
   messager   )r   r   fdonerf   s      r#   on_leavezAComponent._connect_once.<locals>.create_session.<locals>.on_leave  s    HMM< ' "    !?400 2">-```!M$55555 % 4 0 Q Q! !A "Lq111112 2r%   r   c                                                       xj        dz  c_        j                            d|           t	          j        j                   } fd} fd}t	          j        |||           d S )Nra   zsession on_join: {details}r  c                 p    j                             d           fd}t          j        d|           d S )Nmain_successc                  T    	                                    d S # t          $ r Y d S w xY wr   )r   r	   )r   s   r#   r   zeComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success.<locals>.leave'  s=    % '#2 % % % !%%s    
''r   )r   r   r   r   )r   r   rf   r   s     r#   r  zVComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success$  sK    ~666% % % % % (E22222r%   c                     j                             d|            t          j        |                                             d S )Nzmain_error: {err})err)r   r   r   r   r   )r  r  rf   r   s    r#   
main_errorzTComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_error0  sF    ':DDDT3///**,,,,,r%   )re   rj   r   r   r   r   r   r   )	r   r   r   r  r  r  reactorrf   rN   s	   `    r#   on_joinz@Component._connect_once.<locals>.create_session.<locals>.on_join  s    OO%%%..!3..HNN#?NQQQWgFFA
3 
3 
3 
3 
3 
3- - - - - - - '<DDDDDr%   rH   c                     j                             d|           t          j                  s5|sj                             d           d S t          j        d            d S d S )Nz,session on_disconnect: was_clean={was_clean})	was_cleanzSession disconnected uncleanly)r   r   r   r  r   r   )r   r  r  rf   s     r#   on_disconnectzFComponent._connect_once.<locals>.create_session.<locals>.on_disconnect;  s    HNNF"+ #    !?400 6( 6 HMM @     "M$555556 6r%   r   )r   r   r   r   r   r   itemsr   r   add_authenticatorr   _parentr   r   	Exceptionr   r  r   )cfgr   	auth_nameauth_configauthenticatorr  r  r  r   r  r  r  rf   rN   s             r#   create_sessionz/Component._connect_once.<locals>.create_session  s   !$+t{;;CZ*.*>*>s*C*CC.2.B.H.H.J.J A A*I{!+~>> A11+>>>>(<Y(V(V+(V(V11-@@@@A& #'
2 2 2 2 2 2 

7H---
E E E E E E E E. ;*JJvw///
6 6 6 6 6 6 

<777 c     (++T1%%%s   BD 
E*E  Era   c                 ~    xj         dz  c_         t          j                  st          j        |            dS dS )a  
            this may seem redundant after looking at _connect_transport, but
            it will handle a case where something goes wrong in
            _connect_transport itself -- as the only connect our
            caller has is the 'done' future
            ra   N)rk   r   r  r   )r  r  rN   s    r#   on_errorz)Component._connect_once.<locals>.on_errorU  sO     &&!+&& ?4(( (T3'''''( (r%   )
r   r   r   rw   r   r   ri   r   _connect_transportr   )rf   r  rN   r'  r   r)  r  s   ```   @r#   r   zComponent._connect_once  s    .$>#5577	 	 	
 	
 	
 "$$\	 \	 \	 \	 \	 \	 \	 \	| 	""a'""O#Y
 

	( 	( 	( 	( 	( 	( 	AtX...r%   c                 2    |                      d|           dS )z
        A decorator as a shortcut for listening for 'join' events.

        For example::

           @component.on_join
           def joined(session, details):
               print("Session {} joined: {}".format(session, details))
        rH   Nr   rf   r   s     r#   r  zComponent.on_joine  s     	r%   c                 2    |                      d|           dS )zM
        A decorator as a shortcut for listening for 'leave' events.
        r   Nr   r,  s     r#   r  zComponent.on_leaveq       	r%   c                 2    |                      d|           dS )zO
        A decorator as a shortcut for listening for 'connect' events.
        r   Nr   r,  s     r#   
on_connectzComponent.on_connectw  s     		2r%   c                 2    |                      d|           dS )zR
        A decorator as a shortcut for listening for 'disconnect' events.
        r   Nr   r,  s     r#   r  zComponent.on_disconnect}  s     	b!!!!!r%   c                 2    |                      d|           dS )zM
        A decorator as a shortcut for listening for 'ready' events.
        r   Nr   r,  s     r#   on_readyzComponent.on_ready  r.  r%   c                 2    |                      d|           dS )zV
        A decorator as a shortcut for listening for 'connectfailure' events.
        r   Nr   r,  s     r#   on_connectfailurezComponent.on_connectfailure  s     	 "%%%%%r%   )NF)NNNr   NNNNr   )rx   ry   rz   r{   r   r   r   rg   r   r  r  r   r  r  r0  r  r3  r5  r5   r%   r#   r   r   g  s        
 O   .   . W[EI} } } }~  l l l l\1 1 1   B
 
 
    " " "  & & & & &r%   c                 `   
 t          |t                    r|g}t          |          t          k    r/t	          d                    t          |                              |D ]F}t          |t                    s/t	          d                    t          |                              Gt          j                    fdfd

 fd}g }|D ]"} ||          }|                    |           #t          j	        |d          }r fd}	t          j
        ||	|	           |S )	a  
    Internal helper. Use "run" method from autobahn.twisted.wamp or
    autobahn.asyncio.wamp

    This is the generic parts of the run() method so that there's very
    little code in the twisted/asyncio specific run() methods.

    This is called by react() (or run_until_complete() so any errors
    coming out of this should be handled properly. Logging will
    already be started.
    zB"components" must be a list of Component objects - encountered {0}zN"components" must be a list of Component objects - encountereditem of type {0}c                 8                         d| |           |S )Nz-Component '{c}' successfully completed: {arg})cr   r   )compr   r   s     r#   component_successz_run.<locals>.component_success  s!    		ATs	SSS
r%   c                                          d| t          j        |                                         dt          j        |                     d S )NzComponent '{c}' error: {msg})r8  r   zComponent error: {tb}r   )r   r   r   r   r   )r:  r  r   s     r#   component_failurez_run.<locals>.component_failure  sQ    		0De>STU>V>V	WWW		)e.LQ.O.O	PPP tr%   c                     t          j        | j                  }t          j        |t	          |           t	          |                      |S r   )r   r   r   r   r   )r:  r   r=  r;  r  s     r#   component_startz_run.<locals>.component_start  sS     ODJ00%t,,%t,,	
 	
 	

 r%   F)consume_exceptionsc                 J                         d            |            d S )Nz&All components ended; stopping reactorr9  )r   done_callbackr   r  s    r#   all_donez_run.<locals>.all_done  s.    II>???M'3'''''r%   )r   r   r   rE   r   r   r   make_loggerr   gatherr   )r  
componentsrB  r8  r?  dlr:  r   done_drC  r=  r;  r   s   ` `       @@@r#   _runrI    s    *i(( " \
J46$z**++
 
 	

   !Y'' 	##)6$q''??  	 


C        	 	 	 	 	 	 	 
B  OD!!
		!\"777F 8	( 	( 	( 	( 	( 	( 	( 	FHh777Mr%   r   )r   rs   	functoolsr   r   autobahn.utilr   autobahn.websocket.utilr   rD   autobahn.rawsocket.utilrJ   autobahn.wamp.typesr   r   r   autobahn.wamp.exceptionr	   r
   autobahn.wamp.authr   r   autobahn.wamp.serializerr   __all__r$   rZ   objectrL   r   rI  r5   r%   r#   <module>rT     s  8             ) ) ) ) ) ) = = = = = = = = = = = = R R R R R R R R R R E E E E E E E E C C C C C C C C 1 1 1 1 1 1  
63 63 63 63r[ [ [ [|X# X# X# X# X# X# X# X#~f& f& f& f& f& f& f& f&RG G G G G Gr%   