o
    èó·iÕ–  ã                   @   sÎ   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
d„Zddd„ZG dd„ deƒZG dd	„ d	eƒZddd„ZdS )é    N)Úpartial)ÚObservableMixin)Ú	parse_url)ÚComponentConfigÚSubscribeOptionsÚRegisterOptions)ÚSessionNotReadyÚApplicationError)Úcreate_authenticatorÚIAuthenticator)ÚSERID_TO_SERÚ	Componentc                 C   s(  |r|| ƒ n	t | tƒstdƒ‚t | tƒr’d| vrtdƒ‚| d dvr,td | d ¡ƒ‚|  ¡ D ]}|dvr=td |¡ƒ‚q0| d dkrfd	D ]}|| vrStd
 |¡ƒ‚qFdD ]}|| v rctd |¡ƒ‚qVdS | d dkrŽdD ]}|| vr{td |¡ƒ‚qndD ]}|| v r‹td |¡ƒ‚q~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Úk© r!   ú]C:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\autobahn/wamp/component.pyÚ_validate_endpoint1   s^   

ÿ
	ÿÿÿÿÿÿÿÿÿÿÿÿÚr#   c              
   C   sŒ  t |ƒtkrtd t |ƒ¡ƒ‚g d¢}| ¡ D ]}||vr$td |¡ƒ‚qd}d|v r?|d dvr:td |d ¡ƒ‚|d }nd|d< d|v rO|dkrOtd	ƒ‚| dd
¡}|d
ur{| ¡ D ]}|dvrjtd |¡ƒ‚q]dD ]}||vrztd |¡ƒ‚qmtƒ }d|v r”|d }t|tƒs”td t |ƒ¡ƒ‚| d¡}|dk�r"dD ]}	|	|vr­td |	¡ƒ‚q d|vrÆt|d ƒ\}
}}}}}d|||
dœ}n	|d }t	||ƒ d|v r×tdƒ‚d|v �rt|d t
tfƒsétdƒ‚tdd„ |d D ƒƒsøtdƒ‚t ¡ }|d D ]}||v�rtd |d dd„ |D ƒ¡¡ƒ‚�q | dd d!g¡}n}|d"k�r›d|v�rh|d  d#¡�r>t|d ƒ\}}}n|d  d$¡�rSt|d ƒ\}}}}}}ntƒ ‚|d%k�rad%|d&œ}nd||d'œ}n|d }d|v �rutd(ƒ‚|d
u�r~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°||	 ||	< �q£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   )r/   Ú	rawsocketzInvalid transport type {}r-   z3proxy= only supported for type=websocket transportsNr   z Unknown key '{}' in proxy configzProxy config requires '{}'r'   zoptions must be a dict, not {}r.   )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                 S   s   g | ]	}t |ttfƒ‘qS r!   )r   Ústr©Ú.0Úsr!   r!   r"   Ú
<listcomp>¿   s    ÿÿz%_create_transport.<locals>.<listcomp>z-Invalid serializer '{}' (expected one of: {})z, c                 S   s   g | ]}t |ƒ‘qS r!   )Úreprr2   r!   r!   r"   r5   É   s    ZcborÚjsonr0   Ú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&   r-   r'   r.   )r   r   r   r   r   ÚgetZformaTr   Úparse_ws_urlr#   ÚlistÚtupleÚallr   ÚjoinÚ
startswithÚparse_rs_urlÚRuntimeErrorr1   Ú
_Transport)ÚindexÚ	transportr   Zvalid_transport_keysr    r:   r-   r'   r.   ÚkeyZ	is_securer   r   Úresourcer   ÚparamsZendpoint_configZvalid_serializersÚserialZserializer_configZisSecureÚkwr!   r!   r"   Ú_create_transportj   sî   ÿÿ
ÿÿÿÿÿ
ÿ

ÿü	

þ
þÿÿ


þý



€ÿ
ø	÷rL   c                   @   sR   e Zd ZdZ								ddd„Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Z	dS )rD   z@
    Thin-wrapper for WAMP transports used by a Connection.
    éÿÿÿÿé,  ç      ø?çš™™™™™¹?Nc                 C   sŒ   |du rt ƒ }|| _|| _|| _|| _|| _|| _|| _| jdkr+t|ƒdkr+t	dƒ‚|| _
|| _|| _|	| _|
| _|| _d| _|  ¡  dS )z	
        Nr0   é   z5'rawsocket' transport requires exactly one serializerF)r   Úidxr   r$   r   r'   r.   r&   Úlenr   r(   r)   r*   r+   r,   r-   Ú_permanent_failureÚreset)ÚselfrR   r:   r$   r   r&   r(   r)   r*   r+   r,   r-   r'   r.   r!   r!   r"   Ú__init__  s*   ÿz_Transport.__init__c                 C   s   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©rV   r!   r!   r"   rU   5  s   z_Transport.resetc                 C   s
   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)rT   r\   r!   r!   r"   Úfailed>  s   
z_Transport.failedc                 C   s(   | j rdS | jdkrdS | j| jd k S )NFrM   TrQ   )rT   r(   rX   r\   r!   r!   r"   Úcan_reconnectF  s
   
z_Transport.can_reconnectc                 C   sp   | j dkrdS | jdkr| j | jd krtdƒ‚| j| j | _t | j| j| j ¡| _| j| jkr5| j| _| jS )Nr   rM   rQ   zmax reconnects reached)	rX   r(   rC   r[   r+   ÚrandomÚnormalvariater,   r)   r\   r!   r!   r"   Ú
next_delayM  s   
z_Transport.next_delayc                 C   s    t | jtƒr| jd S t| jƒS )zF
        returns a human-readable description of the endpoint
        r   N)r   r   r   r6   r\   r!   r!   r"   Údescribe_endpointZ  s   

z_Transport.describe_endpoint)rM   rN   rO   rO   rP   NNN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__rW   rU   r]   r^   ra   rb   r!   r!   r!   r"   rD     s     
ø(	rD   c                   @   sŠ   e Zd ZdZdZ	 ddd„Zddd„Z		d d	d
„Zdd„ Zd!dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )"r   z‚
    A WAMP application component. A component holds configuration for
    (and knows how to create) transports and sessions.
    NFc                    ó,   ˆdu st ˆtƒsJ ‚‡ ‡‡‡fd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dd„}ˆ  d|¡ ˆ S )Nc                    ó   | j ˆˆˆˆ d�S )N)Útopicr'   Úcheck_types)Ú	subscribe©ÚsessionÚdetails)rk   Úfnr'   rj   r!   r"   Údo_subscriptionƒ  ó   z?Component.subscribe.<locals>.decorator.<locals>.do_subscriptionr@   ©Úon)rp   rq   ©rk   r'   rV   rj   ©rp   r"   Ú	decorator�  ó   z&Component.subscribe.<locals>.decorator)r   r   )rV   rj   r'   rk   rw   r!   ru   r"   rl   r  ó   zComponent.subscribec                    rg   )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                    rh   )Nc                    ri   )N)Z	procedurer'   rk   )Úregisterrm   )rk   rp   r'   Úurir!   r"   Údo_registrationš  rr   z>Component.register.<locals>.decorator.<locals>.do_registrationr@   rs   )rp   r|   ©rk   r'   rV   r{   rv   r"   rw   ˜  rx   z%Component.register.<locals>.decorator)r   r   )rV   r{   r'   rk   rw   r!   r}   r"   rz   ‰  ry   zComponent.registerÚrealm1c	                 C   s  |   g d¢¡ |durt|ƒstdƒ‚|| _|dur"t|ƒs"tdƒ‚|| _|du r+d}t|ttfƒr=|}	d|	dœ}
|
g}nt|tƒrE|g}g | _t	|ƒD ]\}}
t
|
ƒtkr\d|
dœ}n|
}| j t||| jƒ¡ qL|pmi | _|rt|| _|| _|| _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Úconnectr@   Ú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/wsr/   )r   r$   F)Zset_valid_eventsÚcallabler   Ú	_is_fatalÚ_entryr   r1   r   Ú_transportsÚ	enumerater   ÚappendrL   Z_check_native_endpointÚ_authenticationÚsession_factoryÚ_realmÚ_extraÚ_delay_fÚ_done_fÚ_sessionÚ	_stopping)rV   ÚmainÚ
transportsÚconfigÚrealmÚextraZauthenticationrŒ   Úis_fatalr$   rF   rR   Ú
_transportr!   r!   r"   rW      sL   9ÿþ
þÿ

zComponent.__init__c                 C   s   | j D ]	}| ¡ r dS qdS )NTF)rˆ   r^   )rV   rF   r!   r!   r"   Ú_can_reconnect  s
   
ÿzComponent._can_reconnectc                    s¾   ˆj durt ¡ ‰‡fdd„}t ˆj ||¡ ˆS t ¡ ˆ_ ‡fdd„}t ˆj ||¡ t ˆj¡‰dg‰‡fdd„‰‡‡‡‡fd	d
„‰ ‡ ‡‡‡‡fdd„‰ˆ dˆˆ¡}t |ˆˆ¡ ˆ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                    s   t  ˆ | ¡ d S ©N)ÚtxaioÚresolve©Úarg)Údr!   r"   Ú_cb;  s   zComponent._start.<locals>._cbc                    s
   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ž   r\   r!   r"   Ú_resetE  s   z Component._start.<locals>._resetr   c                    s\   d ˆ _ ˆ jrt ˆ jd ¡ d S ˆ jjdt | ¡d� ˆ jjdt 	| ¡d� t 
ˆ j| ¡ d S )NzInternal error {msg}©Úmsgú{tb}©Útb)r�   r’   rœ   r�   r�   ÚlogÚinfoÚfailure_messageÚdebugÚfailure_format_tracebackÚreject)Úfailr\   r!   r"   ÚerrorU  s   zComponent._start.<locals>.errorc                    sb   d ˆ_ ‡‡‡fdd„‰ ‡fdd„‰‡ ‡fdd„}‡fdd„}t ˆjˆˆd	 ¡}t |||¡ d S )
Nc                    s  ˆ j jdt | ¡d� ˆ j jdt | ¡d� t| jtƒr(ˆ j jd| j 	¡ d� n7t| jt
ƒr:ˆ j jdt | ¡d� n%ˆ  | j¡rT| jjd d \}}}ˆ j jd	|d
� nˆ j jdt | ¡d� ˆ jd u rgd}nˆ  | j¡}|r{ˆ j  d¡ ˆd  ¡  t 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©   Z_is_ssl_errorÚargsr†   r]   Ú
call_later)r®   Zssl_libZssl_funcZ
ssl_reasonr˜   )rV   Útransport_candidateÚtransport_checkr!   r"   Úhandle_connect_errore  s*   þ
zGComponent._start.<locals>.attempt_connect.<locals>.handle_connect_errorc                    s>   t  ¡ ‰ ˆ dˆˆj¡}t  |‡ ‡fdd„‡ ‡fdd„¡ ˆ S )Nr„   c                    ó   t  ˆ ˆ¡S r›   ©rœ   r­   ©Ú_©Zchain_fr®   r!   r"   Ú<lambda>ž  ó    zYComponent._start.<locals>.attempt_connect.<locals>.notify_connect_error.<locals>.<lambda>c                    r¹   r›   rº   r»   r½   r!   r"   r¾   Ÿ  r¿   )rœ   Úcreate_futureÚfirer±   Úadd_callbacks)r®   Z	handler_fr\   r½   r"   Únotify_connect_error•  s   ýzGComponent._start.<locals>.attempt_connect.<locals>.notify_connect_errorc                    s   ˆ| ƒ}t  |d ˆ ¡ d S r›   )rœ   rÂ   )r®   Znotify_f©r¸   rÃ   r!   r"   Úconnect_error£  s   z@Component._start.<locals>.attempt_connect.<locals>.connect_errorc                    s   t  ˆ jd ¡ d S r›   )rœ   r�   r�   )Úxr\   r!   r"   Úsession_done§  rr   z?Component._start.<locals>.attempt_connect.<locals>.session_doner   )r�   rœ   Ú	as_futureÚ_connect_oncerÂ   )r¼   rÅ   rÇ   Z	connect_f)ÚlooprV   r¶   r·   rÄ   r"   Úattempt_connectb  s   0þz)Component._start.<locals>.attempt_connectc              
      sÀ   ˆj  d¡ ˆ ¡ s1d}ˆj  |¡ zt|ƒ‚ ty0 } zt ˆj|¡ W Y d }~d S d }~ww 	 tˆƒ}| 	¡ r?|ˆd< q@q2| 
¡ }ˆj jd|j|j|d� t |¡ˆ_t ˆ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})Ztransport_idxZtransport_urlZtransport_delay)r¨   r«   rš   r©   rC   rœ   r­   r�   Únextr^   ra   ÚwarnrR   r$   Úsleepr�   rÂ   )r¼   Úerr_msgÚerF   Údelay)rË   r¯   rV   r¶   Útransport_genr!   r"   r·   °  s4   €þúüz)Component._start.<locals>.transport_checkr   )r�   rœ   rÀ   rÂ   Ú	itertoolsÚcyclerˆ   rÁ   )rV   rÊ   r¡   r¢   Zstart_fr!   )rË   r    r¯   rÊ   rV   r¶   r·   rÒ   r"   Ú_start&  s    

N zComponent._startc                 C   sZ   d| _ | jr| j ¡ r| j ¡ S | jrt tj| j¡S t | j	¡s(t 
| j	d ¡ t d ¡S )NT)r’   r‘   Zis_attachedr‚   r�   rœ   rÈ   ÚcancelÚ	is_calledr�   r�   Zcreate_future_successr\   r!   r!   r"   ÚstopÔ  s   

zComponent.stopc                    st   ˆj jdˆjˆ ¡ d� t ¡ ‰ ‡ ‡‡‡fdd„}ˆ jd7  _t ˆjˆˆ|ˆ ¡}‡ ‡fdd„}t 	|d |¡ ˆ S )NzWconnecting once using transport type "{transport_type}" over endpoint "{endpoint_desc}")Ztransport_typeZendpoint_descc            
   
      sþ   t ˆjˆjƒ} z,ˆ | ¡ ˆ_}ˆj ¡ D ]\}}t|tƒr$| 	|¡ qt
|fi |¤Ž}| 	|¡ qW n tyK } zt |¡}t ˆ |¡ ‚ d }~ww ˆ|_‡ ‡fdd„}| d|¡ ‡ ‡‡‡fdd„}ˆjd urp| d|¡ ‡ ‡fdd„}	| d	|	¡ |S )
Nc                    s\   ˆj jd|d� t ˆ ¡s,|jdv rt ˆ d ¡ d S t t|j|jƒ¡}t 	ˆ |¡ d S d S )Nz"session leaving '{details.reason}'©ro   )zwamp.close.normalzwamp.close.goodbye_and_out)
r¨   r©   rœ   r×   r°   r�   Úcreate_failurer	   Úmessager­   )rn   ro   Úf©ÚdonerV   r!   r"   Úon_leave  s   þ

ÿùzAComponent._connect_once.<locals>.create_session.<locals>.on_leaver‚   c                    sf   ˆ  ¡  ˆ jd7  _ˆjjd|d� t ˆjˆˆ ¡}‡‡ fdd„}‡‡‡ fdd„}t |||¡ d S )NrQ   zsession on_join: {details}rÙ   c                    s(   ˆ j  d¡ ‡fdd„}t d|¡ d S )NÚmain_successc                      s$   zˆ   ¡  W d S  ty   Y d S w r›   )r‚   r   r!   ©rn   r!   r"   r‚   '  s
   ýzeComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_success.<locals>.leaver   )r¨   r«   rœ   rµ   )r¼   r‚   )rV   rn   r!   r"   rà   $  s   zVComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_successc                    s(   ˆj jd| d� t ˆ | ¡ ˆ ¡  d S )Nzmain_error: {err}©Úerr)r¨   r«   rœ   r­   rƒ   râ   )rÞ   rV   rn   r!   r"   Ú
main_error0  s   zTComponent._connect_once.<locals>.create_session.<locals>.on_join.<locals>.main_error)rU   rY   r¨   r«   rœ   rÈ   r‡   rÂ   )rn   ro   r    rà   rä   ©rÞ   ÚreactorrV   rF   rá   r"   Úon_join  s   z@Component._connect_once.<locals>.create_session.<locals>.on_joinr@   c                    sB   ˆj jd|d� t ˆ ¡s|sˆj  d¡ d S t ˆ d ¡ d S d S )Nz,session on_disconnect: was_clean={was_clean})Ú	was_cleanzSession disconnected uncleanly)r¨   r«   rœ   r×   rÍ   r�   )rn   rè   rÝ   r!   r"   Úon_disconnect;  s   þ
ÿøzFComponent._connect_once.<locals>.create_session.<locals>.on_disconnectrƒ   )r   r�   rŽ   rŒ   r‘   r‹   Úitemsr   r   Zadd_authenticatorr
   Ú	Exceptionrœ   rÚ   r­   Ú_parentrt   r‡   )
Úcfgrn   Z	auth_nameZauth_configZauthenticatorrÐ   rÜ   rß   rç   ré   rå   r!   r"   Úcreate_sessionð  s0   
û
€û
z/Component._connect_once.<locals>.create_sessionrQ   c                    s,   ˆ j d7  _ t ˆ ¡st ˆ | ¡ 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
            rQ   N)rZ   rœ   r×   r­   râ   )rÞ   rF   r!   r"   Úon_errorU  s   
ÿz)Component._connect_once.<locals>.on_error)
r¨   r©   r   rb   rœ   rÀ   rX   rÈ   Z_connect_transportrÂ   )rV   ræ   rF   rî   r    rï   r!   rå   r"   rÉ   ä  s   ü^þzComponent._connect_oncec                 C   ó   |   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))
        r@   Nrs   ©rV   rp   r!   r!   r"   rç   e  s   
zComponent.on_joinc                 C   rð   )zM
        A decorator as a shortcut for listening for 'leave' events.
        r‚   Nrs   rñ   r!   r!   r"   rß   q  ó   zComponent.on_leavec                 C   rð   )zO
        A decorator as a shortcut for listening for 'connect' events.
        r€   Nrs   rñ   r!   r!   r"   Ú
on_connectw  rò   zComponent.on_connectc                 C   rð   )zR
        A decorator as a shortcut for listening for 'disconnect' events.
        rƒ   Nrs   rñ   r!   r!   r"   ré   }  rò   zComponent.on_disconnectc                 C   rð   )zM
        A decorator as a shortcut for listening for 'ready' events.
        r�   Nrs   rñ   r!   r!   r"   Úon_readyƒ  rò   zComponent.on_readyc                 C   rð   )zV
        A decorator as a shortcut for listening for 'connectfailure' events.
        r„   Nrs   rñ   r!   r!   r"   Úon_connectfailure‰  rò   zComponent.on_connectfailure)NF)NNNr~   NNNNr›   )rc   rd   re   rf   rŒ   rl   rz   rW   rš   rÕ   rØ   rÉ   rç   rß   ró   ré   rô   rõ   r!   r!   r!   r"   r   g  s*    


ÿ
 / c           
         sØ   t |tƒr|g}t|ƒtkrtd t|ƒ¡ƒ‚|D ]}t |tƒs)td t|ƒ¡ƒ‚qt ¡ ‰‡fdd„‰‡fdd„‰ ‡ ‡‡fdd„}g }|D ]}||ƒ}| |¡ qFtj	|d	d
�}ˆrj‡‡‡fdd„}	t 
||	|	¡ |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                    s   ˆ j d| |d� |S )Nz-Component '{c}' successfully completed: {arg})ÚcrŸ   ©r«   )ÚcomprŸ   ©r¨   r!   r"   Úcomponent_success±  s   z_run.<locals>.component_successc                    s.   ˆ j d| t |¡d� ˆ jdt |¡d� d S )NzComponent '{c}' error: {msg})rö   r¤   zComponent error: {tb}r¦   )r¯   rœ   rª   r«   r¬   )rø   rÜ   rù   r!   r"   Úcomponent_failureµ  s   z_run.<locals>.component_failurec                    s,   t  | jˆ¡}t  |tˆ| ƒtˆ | ƒ¡ |S r›   )rœ   rÈ   r   rÂ   r   )rø   r    )rû   rú   ræ   r!   r"   Úcomponent_start½  s   ýz_run.<locals>.component_startF)Zconsume_exceptionsc                    s   ˆ  d¡ ˆ ˆ| ƒ d S )Nz&All components ended; stopping reactorr÷   rž   )Údone_callbackr¨   ræ   r!   r"   Úall_doneÒ  s   
z_run.<locals>.all_doneN)r   r   r   r=   r   r   rœ   Zmake_loggerrŠ   ÚgatherrÂ   )
ræ   Ú
componentsrý   rö   rü   Údlrø   r    Zdone_drþ   r!   )rû   rú   rý   r¨   ræ   r"   Ú_run�  s6   

þ

þÿr  r›   )rÓ   r_   Ú	functoolsr   rœ   Zautobahn.utilr   Zautobahn.websocket.utilr   r<   Zautobahn.rawsocket.utilrB   Zautobahn.wamp.typesr   r   r   Zautobahn.wamp.exceptionr   r	   Zautobahn.wamp.authr
   r   Zautobahn.wamp.serializerr   Ú__all__r#   rL   ÚobjectrD   r   r  r!   r!   r!   r"   Ú<module>   s.   ÿ

9 _    -