<s> from __future__ import absolute_import <EOL> import inspect <EOL> import six <EOL> from twisted . internet . defer import inlineCallbacks <EOL> from autobahn . wamp import protocol <EOL> from autobahn . wamp . types import ComponentConfig <EOL> from autobahn . websocket . util import parse_url <EOL> from autobahn . twisted . websocket import WampWebSocketClientFactory <EOL> import txaio <EOL> txaio . use_twisted ( ) <EOL> __all__ = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ] <EOL> try : <EOL> from twisted . application import service <EOL> except ( ImportError , SyntaxError ) : <EOL> service = None <EOL> __all__ . pop ( __all__ . index ( '<STR_LIT>' ) ) <EOL> class ApplicationSession ( protocol . ApplicationSession ) : <EOL> """<STR_LIT>""" <EOL> class ApplicationSessionFactory ( protocol . ApplicationSessionFactory ) : <EOL> """<STR_LIT>""" <EOL> session = ApplicationSession <EOL> """<STR_LIT>""" <EOL> class ApplicationRunner ( object ) : <EOL> """<STR_LIT>""" <EOL> log = txaio . make_logger ( ) <EOL> def __init__ ( self , url , realm , extra = None , serializers = None , ssl = None , proxy = None ) : <EOL> """<STR_LIT>""" <EOL> assert ( type ( url ) == six . text_type ) <EOL> assert ( realm is None or type ( realm ) == six . text_type ) <EOL> assert ( extra is None or type ( extra ) == dict ) <EOL> assert ( proxy is None or type ( proxy ) == dict ) <EOL> self . url = url <EOL> self . realm = realm <EOL> self . extra = extra or dict ( ) <EOL> self . serializers = serializers <EOL> self . ssl = ssl <EOL> self . proxy = proxy <EOL> def run ( self , make , start_reactor = True ) : <EOL> """<STR_LIT>""" <EOL> if start_reactor : <EOL> from twisted . internet import reactor <EOL> txaio . use_twisted ( ) <EOL> txaio . config . loop = reactor <EOL> txaio . start_logging ( level = '<STR_LIT:info>' ) <EOL> isSecure , host , port , resource , path , params = parse_url ( self . url ) <EOL> def create ( ) : <EOL> cfg = ComponentConfig ( self . realm , self . extra ) <EOL> try : <EOL> session = make ( cfg ) <EOL> except Exception as e : <EOL> if start_reactor : <EOL> self . log . error ( "<STR_LIT>" , err = e ) <EOL> reactor . stop ( ) <EOL> else : <EOL> raise <EOL> else : <EOL> return session <EOL> transport_factory = WampWebSocketClientFactory ( create , url = self . url , serializers = self . serializers , proxy = self . proxy ) <EOL> transport_factory . noisy = False <EOL> context_factory = None <EOL> if self . ssl is not None : <EOL> if not isSecure : <EOL> raise RuntimeError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> self . __class__ . __name__ ) <EOL> context_factory = self . ssl <EOL> elif isSecure : <EOL> from twisted . internet . ssl import optionsForClientTLS <EOL> context_factory = optionsForClientTLS ( host ) <EOL> from twisted . internet import reactor <EOL> if self . proxy is not None : <EOL> from twisted . internet . endpoints import TCP4ClientEndpoint <EOL> client = TCP4ClientEndpoint ( reactor , self . proxy [ '<STR_LIT:host>' ] , self . proxy [ '<STR_LIT:port>' ] ) <EOL> transport_factory . contextFactory = context_factory <EOL> elif isSecure : <EOL> from twisted . internet . endpoints import SSL4ClientEndpoint <EOL> assert context_factory is not None <EOL> client = SSL4ClientEndpoint ( reactor , host , port , context_factory ) <EOL> else : <EOL> from twisted . internet . endpoints import TCP4ClientEndpoint <EOL> client = TCP4ClientEndpoint ( reactor , host , port ) <EOL> d = client . connect ( transport_factory ) <EOL> def cleanup ( proto ) : <EOL> if hasattr ( proto , '<STR_LIT>' ) and proto . _session is not None : <EOL> if proto . _session . is_attached ( ) : <EOL> return proto . _session . leave ( ) <EOL> elif proto . _session . is_connected ( ) : <EOL> return proto . _session . disconnect ( ) <EOL> def init_proto ( proto ) : <EOL> reactor . addSystemEventTrigger ( '<STR_LIT>' , '<STR_LIT>' , cleanup , proto ) <EOL> return proto <EOL> d . addCallback ( init_proto ) <EOL> if start_reactor : <EOL> class ErrorCollector ( object ) : <EOL> exception = None <EOL> def __call__ ( self , failure ) : <EOL> self . exception = failure . value <EOL> reactor . stop ( ) <EOL> connect_error = ErrorCollector ( ) <EOL> d . addErrback ( connect_error ) <EOL> reactor . run ( ) <EOL> if connect_error . exception : <EOL> raise connect_error . exception <EOL> else : <EOL> return d <EOL> class _ApplicationSession ( ApplicationSession ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , config , app ) : <EOL> """<STR_LIT>""" <EOL> ApplicationSession . __init__ ( self , config ) <EOL> self . app = app <EOL> @ inlineCallbacks <EOL> def onConnect ( self ) : <EOL> """<STR_LIT>""" <EOL> yield self . app . _fire_signal ( '<STR_LIT>' ) <EOL> self . join ( self . config . realm ) <EOL> @ inlineCallbacks <EOL> def onJoin ( self , details ) : <EOL> """<STR_LIT>""" <EOL> for uri , proc in self . app . _procs : <EOL> yield self . register ( proc , uri ) <EOL> for uri , handler in self . app . _handlers : <EOL> yield self . subscribe ( handler , uri ) <EOL> yield self . app . _fire_signal ( '<STR_LIT>' ) <EOL> @ inlineCallbacks <EOL> def onLeave ( self , details ) : <EOL> """<STR_LIT>""" <EOL> yield self . app . _fire_signal ( '<STR_LIT>' ) <EOL> self . disconnect ( ) <EOL> @ inlineCallbacks <EOL> def onDisconnect ( self ) : <EOL> """<STR_LIT>""" <EOL> yield self . app . _fire_signal ( '<STR_LIT>' ) <EOL> class Application ( object ) : <EOL> """<STR_LIT>""" <EOL> log = txaio . make_logger ( ) <EOL> def __init__ ( self , prefix = None ) : <EOL> """<STR_LIT>""" <EOL> self . _prefix = prefix <EOL> self . _procs = [ ] <EOL> self . _handlers = [ ] <EOL> self . _signals = { } <EOL> self . session = None <EOL> def __call__ ( self , config ) : <EOL> """<STR_LIT>""" <EOL> assert ( self . session is None ) <EOL> self . session = _ApplicationSession ( config , self ) <EOL> return self . session <EOL> def run ( self , url = u"<STR_LIT>" , realm = u"<STR_LIT>" , start_reactor = True ) : <EOL> """<STR_LIT>""" <EOL> runner = ApplicationRunner ( url , realm ) <EOL> return runner . run ( self . __call__ , start_reactor ) <EOL> def register ( self , uri = None ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> if uri : <EOL> _uri = uri <EOL> else : <EOL> assert ( self . _prefix is not None ) <EOL> _uri = "<STR_LIT>" . format ( self . _prefix , func . __name__ ) <EOL> if inspect . isgeneratorfunction ( func ) : <EOL> func = inlineCallbacks ( func ) <EOL> self . _procs . append ( ( _uri , func ) ) <EOL> return func <EOL> return decorator <EOL> def subscribe ( self , uri = None ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> if uri : <EOL> _uri = uri <EOL> else : <EOL> assert ( self . _prefix is not None ) <EOL> _uri = "<STR_LIT>" . format ( self . _prefix , func . __name__ ) <EOL> if inspect . isgeneratorfunction ( func ) : <EOL> func = inlineCallbacks ( func ) <EOL> self . _handlers . append ( ( _uri , func ) ) <EOL> return func <EOL> return decorator <EOL> def signal ( self , name ) : <EOL> """<STR_LIT>""" <EOL> def decorator ( func ) : <EOL> if inspect . isgeneratorfunction ( func ) : <EOL> func = inlineCallbacks ( func ) <EOL> self . _signals . setdefault ( name , [ ] ) . append ( func ) <EOL> return func <EOL> return decorator <EOL> @ inlineCallbacks <EOL> def _fire_signal ( self , name , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> for handler in self . _signals . get ( name , [ ] ) : <EOL> try : <EOL> yield handler ( * args , ** kwargs ) <EOL> except Exception as e : <EOL> self . log . info ( "<STR_LIT>" , err = e ) <EOL> if service : <EOL> class Service ( service . MultiService ) : <EOL> """<STR_LIT>""" <EOL> factory = WampWebSocketClientFactory <EOL> def __init__ ( self , url , realm , make , extra = None , context_factory = None ) : <EOL> """<STR_LIT>""" <EOL> self . url = url <EOL> self . realm = realm <EOL> self . extra = extra or dict ( ) <EOL> self . make = make <EOL> self . context_factory = context_factory <EOL> service . MultiService . __init__ ( self ) <EOL> self . setupService ( ) <EOL> def setupService ( self ) : <EOL> """<STR_LIT>""" <EOL> is_secure , host , port , resource , path , params = parse_url ( self . url ) <EOL> def create ( ) : <EOL> cfg = ComponentConfig ( self . realm , self . extra ) <EOL> session = self . make ( cfg ) <EOL> return session <EOL> transport_factory = self . factory ( create , url = self . url ) <EOL> if is_secure : <EOL> from twisted . application . internet import SSLClient <EOL> ctx = self . context_factory <EOL> if ctx is None : <EOL> from twisted . internet . ssl import optionsForClientTLS <EOL> ctx = optionsForClientTLS ( host ) <EOL> client = SSLClient ( host , port , transport_factory , contextFactory = ctx ) <EOL> else : <EOL> if self . context_factory is not None : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> from twisted . application . internet import TCPClient <EOL> client = TCPClient ( host , port , transport_factory ) <EOL> client . setServiceParent ( self ) <EOL> class Session ( ApplicationSession ) : <EOL> def onJoin ( self , details ) : <EOL> return self . on_join ( details ) <EOL> def onLeave ( self , details ) : <EOL> return self . on_leave ( details ) <EOL> def onDisconnect ( self ) : <EOL> return self . on_disconnect ( ) <EOL> def on_join ( self ) : <EOL> pass <EOL> def on_leave ( self , details ) : <EOL> self . disconnect ( ) <EOL> def on_disconnect ( self ) : <EOL> pass </s>
