def create_server(app, port): ## # create a Twisted Web resource for our WebSocket server ## ws_factory = WebSocketServerFactory(u"ws://127.0.0.1:5000", debug=app.debug, debugCodePaths=app.debug) ws_factory.protocol = NotificationService ws_resource = WebSocketResource(ws_factory) ## # create a Twisted Web WSGI resource for our Flask server ## wsgi_resource = WSGIResource(reactor, reactor.getThreadPool(), app) ## # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff ## root_resource = WSGIRootResource(wsgi_resource, {'notification-service': ws_resource}) ## # create a Twisted Web Site and run everything ## site = Site(root_resource) reactor.listenTCP(port, site) reactor.run()
def bind(self): """ Start listening on the port specified """ factory = WebSocketServerFactory(debug=False) factory.noisy = False factory.server = self factory.protocol = MdcloudWebsocketServerProtocol web_resource = File(resource_filename(__name__, 'static/build/client')) rootResource = WSGIRootResource(web_resource, {'ws': WebSocketResource(factory)}) if not self.no_ssl and self.settings and self.settings.ssl.enabled: print '*' * 60 print 'Running in secure mode' print 'Ssl key: %s' % self.settings.ssl.key print 'Ssl certificate: %s' % self.settings.ssl.cert print '*' * 60 listen_ssl(self.port, Site(rootResource), interface=self.settings.websocket_ip) else: print '*' * 60 print 'Running on 0.0.0.0 without SSL' print '*' * 60 reactor.listenTCP(self.port, Site(rootResource), interface='0.0.0.0')
def create(transport, path, config): personality = transport.worker.personality personality.WEB_SERVICE_CHECKERS['wsgi'](personality, config) reactor = transport.worker.components_shared['reactor'] if 'module' not in config: raise ApplicationError('crossbar.error.invalid_configuration', 'missing WSGI app module') if 'object' not in config: raise ApplicationError('crossbar.error.invalid_configuration', 'missing WSGI app object') # import WSGI app module and object mod_name = config['module'] try: mod = importlib.import_module(mod_name) except ImportError as e: raise ApplicationError( 'crossbar.error.invalid_configuration', 'WSGI app module "{}" import failed: {} - Python search path was {}'.format(mod_name, e, sys.path)) obj_name = config['object'] if obj_name not in mod.__dict__: raise ApplicationError('crossbar.error.invalid_configuration', 'WSGI app object "{}" not in module "{}"'.format(obj_name, mod_name)) else: app = getattr(mod, obj_name) # Create a thread-pool for running the WSGI requests in pool = ThreadPool(maxthreads=config.get('maxthreads', 20), minthreads=config.get('minthreads', 0), name='crossbar_wsgi_threadpool') reactor.addSystemEventTrigger('before', 'shutdown', pool.stop) pool.start() # Create a Twisted Web WSGI resource from the user's WSGI application object try: resource = WSGIResource(reactor, pool, app) if path == '/': resource = WSGIRootResource(resource, {}) except Exception as e: raise ApplicationError('crossbar.error.invalid_configuration', 'could not instantiate WSGI resource: {}'.format(e)) else: return RouterWebServiceWsgi(transport, path, config, resource)
def make_service(reactor=None): if reactor is None: from twisted.internet import reactor # create root service root = service.MultiService() # MQTT mqttFactory = MQTTFactory(profile=MQTTFactory.PUBLISHER) mqttEndpoint = clientFromString(reactor, settings.MQTT_BROKER_URI) mqttService = MQTTService(mqttEndpoint, mqttFactory) mqttService.setServiceParent(root) # create a Twisted Web resource for our WebSocket server wsFactory = SerialToWebsocketServerFactory(settings.WS_URI) wsResource = WebSocketResource(wsFactory) # create a Twisted Web WSGI resource for our Flask server wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), create_app()) # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff rootResource = WSGIRootResource(wsgiResource, {settings.WS_PATH: wsResource}) # create a Twisted Web Site site = Site(rootResource) # create service and add it to root wsService = strports.service(settings.SERVICE_URI, site) wsService.setName('web') wsService.setServiceParent(root) # serial port monitor SerialPort(SerialProtocol(wsFactory, mqttService), settings.SERIAL_PORT, reactor, baudrate=settings.SERIAL_BAUDRATE) return root
def main(): ''' Punto de entrada de la aplicacion. ''' # Habilitamos la interfaz Web solo si hay conexion a la red local. if CONFIG['NC_ADDRESS'] is not None: # Creamos un thread pool para la aplicacion. threadPool = ThreadPool(maxthreads=CONFIG['SERVER_MAX_THREADS']) threadPool.start() reactor.addSystemEventTrigger('before', 'shutdown', threadPool.stop) app.mutex = threading.Lock() # Creamos los diferentes recursos que servira el servidor de Twisted. wsgiResource = WSGIResource(reactor, threadPool, app) staticResource = File(STATIC_FILES_PATH) tmpCSVResource = File('/tmp') webSocketFactory = WebSocketServerFactory('ws://{0}:{1}'.format( CONFIG['SERVER_INTERFACE'], CONFIG['SERVER_PORT'])) webSocketFactory.protocol = LibraServerProtocol webSocketResource = WebSocketResource(webSocketFactory) rootResource = WSGIRootResource( wsgiResource, { 'static': staticResource, 'ws': webSocketResource, 'csv': tmpCSVResource }) site = Site(rootResource) reactor.listenTCP(CONFIG['SERVER_PORT'], site) # Mostramos si hay conexion a la red local. if not CONFIG['DEVELOPMENT']: if CONFIG['NC_ADDRESS'] is not None: lcd.showMessage('{0}'.format(CONFIG['NC_ADDRESS']), '{0}'.format(CONFIG['SERVER_PORT'])) else: lcd.showMessage('Desconectado') reactor.run()
def start_server(host='127.0.0.1', port=8080): relay.start(1) # create a Twisted Web resource for our WebSocket server wsFactory = WebSocketServerFactory(u"ws://{}:{}".format(host, port)) wsFactory.protocol = WaitingServerProtocol wsResource = WebSocketResource(wsFactory) # create a Twisted Web WSGI resource for our Flask server wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), app) # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff rootResource = WSGIRootResource(wsgiResource, {b'ws': wsResource}) # create a Twisted Web Site and run everything site = Site(rootResource) reactor.listenTCP(8080, site) reactor.run()
def start_server(): # log.startLogging(sys.stdout) # create a Twisted Web resource for our WebSocket server wsFactory = WebSocketServerFactory("ws://127.0.0.1:5000") wsFactory.protocol = ChronosWebSocketProtocol wsResource = WebSocketResource(wsFactory) # create a Twisted Web WSGI resource for our Flask server wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), app) # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff rootResource = WSGIRootResource(wsgiResource, {b'ws': wsResource}) # create a Twisted Web Site and run everything site = Site(rootResource) reactor.addSystemEventTrigger('before', 'shutdown', cleanup) reactor.listenTCP(5000, site) reactor.run()
def _site_init(self, debug): # Twisted Web resource for our WAMP factory ws_resource = WebSocketResource(self.factory) # Write hardwire settings to JS file with open(os.path.join(self._hw_dir, 'static', 'js', 'hw-settings.js'), 'w+') as f: f.write('var hw_settings = {port: %d}' % self._port) # Twisted Web resource for static assets hw_static_resource = File(os.path.join(self._hw_dir, 'static')) # Create root resource from either the user's WSGI app, the user's # index.html, or the Hardwire default index.html if self._app: print "Using user-supplied WSGI app..." wsgi_resource = WSGIResource(reactor, reactor.getThreadPool(), self._app) child_resources = {'hw_static': hw_static_resource, \ 'static': static_resource, \ settings.WSURI_SUFFIX: ws_resource} root_resource = WSGIRootResource(wsgi_resource, child_resources) else: user_index_path = os.path.join(self._user_dir, 'index.html') if os.path.isfile(user_index_path): print "Using user-supplied index.html..." index_path = self._user_dir else: print "Using Hardwire default index.html..." index_path = os.path.join(self._hw_dir, 'templates') root_resource = File(index_path) root_resource.putChild("hw_static", hw_static_resource) root_resource.putChild(settings.WSURI_SUFFIX, ws_resource) if debug: log.startLogging(sys.stdout) site = Site(root_resource) site.protocol = HTTPChannelHixie76Aware # needed if Hixie76 is supported reactor.listenTCP(self._port, site)
## wsFactory = WebSocketServerFactory("ws://127.0.0.1:8080", debug=debug, debugCodePaths=debug) wsFactory.protocol = EchoServerProtocol wsFactory.setProtocolOptions( allowHixie76=True) # needed if Hixie76 is to be supported wsResource = WebSocketResource(wsFactory) ## # create a Twisted Web WSGI resource for our Flask server ## wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), app) ## # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff ## rootResource = WSGIRootResource(wsgiResource, {'ws': wsResource}) ## # create a Twisted Web Site and run everything ## site = Site(rootResource) site.protocol = HTTPChannelHixie76Aware # needed if Hixie76 is to be supported reactor.listenTCP(8080, site) reactor.run()
print("Posted file: {}".format(request.files['file'])) # def check_timeout_condition(): # """ # TO BE IMPLEMENTED. # """ # TIMEOUT_DELTA_IN_MINS = 10 # time_now = time.time() # if time_now > TIMEOUT_DELTA_IN_MINS * 60: # # Need to trigger the event of broadcasting to all nodes. # # The nodes to drop everything they were doing. # pass if __name__ == '__main__': log.startLogging(sys.stdout) factory = CloudNodeFactory() factory.protocol = CloudNodeProtocol wsResource = WebSocketResource(factory) wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), app) rootResource = WSGIRootResource(wsgiResource, {b'': wsResource}) site = Site(rootResource) state.init() reactor.listenTCP(8999, site) reactor.run()
def start_router_transport(self, id, config, details=None): """ Start a transport on this router. :param id: The ID of the transport to start. :type id: str :param config: The transport configuration. :type config: dict """ if self.debug: log.msg( "{}.start_router_transport".format(self.__class__.__name__), id, config) ## prohibit starting a transport twice ## if id in self.transports: emsg = "ERROR: could not start transport - a transport with ID '{}'' is already running (or starting)".format( id) log.msg(emsg) raise ApplicationError('crossbar.error.already_running', emsg) ## check configuration ## try: checkconfig.check_router_transport(config) except Exception as e: emsg = "ERROR: invalid router transport configuration ({})".format( e) log.msg(emsg) raise ApplicationError("crossbar.error.invalid_configuration", emsg) else: if self.debug: log.msg("Starting {}-transport on router.".format( config['type'])) ## standalone WAMP-RawSocket transport ## if config['type'] == 'rawsocket': transport_factory = CrossbarWampRawSocketServerFactory( self.session_factory, config) transport_factory.noisy = False ## standalone WAMP-WebSocket transport ## elif config['type'] == 'websocket': transport_factory = CrossbarWampWebSocketServerFactory( self.session_factory, self.config.extra.cbdir, config, self._templates) transport_factory.noisy = False ## Flash-policy file server pseudo transport ## elif config['type'] == 'flashpolicy': transport_factory = FlashPolicyFactory( config.get('allowed_domain', None), config.get('allowed_ports', None)) ## WebSocket testee pseudo transport ## elif config['type'] == 'websocket.testee': transport_factory = WebSocketTesteeServerFactory( config, self._templates) ## Stream testee pseudo transport ## elif config['type'] == 'stream.testee': transport_factory = StreamTesteeServerFactory() ## Twisted Web based transport ## elif config['type'] == 'web': options = config.get('options', {}) ## create Twisted Web root resource ## root_config = config['paths']['/'] root_type = root_config['type'] root_options = root_config.get('options', {}) ## Static file hierarchy root resource ## if root_type == 'static': if 'directory' in root_config: root_dir = os.path.abspath( os.path.join(self.config.extra.cbdir, root_config['directory'])) elif 'package' in root_config: if not 'resource' in root_config: raise ApplicationError( "crossbar.error.invalid_configuration", "missing resource") try: mod = importlib.import_module(root_config['package']) except ImportError as e: emsg = "ERROR: could not import resource '{}' from package '{}' - {}".format( root_config['resource'], root_config['package'], e) log.msg(emsg) raise ApplicationError( "crossbar.error.invalid_configuration", emsg) else: try: root_dir = os.path.abspath( pkg_resources.resource_filename( root_config['package'], root_config['resource'])) except Exception as e: emsg = "ERROR: could not import resource '{}' from package '{}' - {}".format( root_config['resource'], root_config['package'], e) log.msg(emsg) raise ApplicationError( "crossbar.error.invalid_configuration", emsg) else: mod_version = getattr(mod, '__version__', '?.?.?') log.msg( "Loaded static Web resource '{}' from package '{} {}' (filesystem path {})" .format(root_config['resource'], root_config['package'], mod_version, root_dir)) else: raise ApplicationError( "crossbar.error.invalid_configuration", "missing web spec") root_dir = root_dir.encode( 'ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 if self.debug: log.msg("Starting Web service at root directory {}".format( root_dir)) ## create resource for file system hierarchy ## if root_options.get('enable_directory_listing', False): root = File(root_dir) else: root = FileNoListing(root_dir) ## set extra MIME types ## root.contentTypes.update(EXTRA_MIME_TYPES) if 'mime_types' in root_options: root.contentTypes.update(root_options['mime_types']) patchFileContentTypes(root) ## render 404 page on any concrete path not found ## root.childNotFound = Resource404(self._templates, root_dir) ## WSGI root resource ## elif root_type == 'wsgi': if not _HAS_WSGI: raise ApplicationError( "crossbar.error.invalid_configuration", "WSGI unsupported") wsgi_options = root_config.get('options', {}) if not 'module' in root_config: raise ApplicationError( "crossbar.error.invalid_configuration", "missing module") if not 'object' in root_config: raise ApplicationError( "crossbar.error.invalid_configuration", "missing object") try: mod = importlib.import_module(root_config['module']) except ImportError: raise ApplicationError( "crossbar.error.invalid_configuration", "module import failed") else: if not root_config['object'] in mod.__dict__: raise ApplicationError( "crossbar.error.invalid_configuration", "object not in module") else: app = getattr(mod, root_config['object']) ## create a Twisted Web WSGI resource from the user's WSGI application object try: wsgi_resource = WSGIResource(reactor, reactor.getThreadPool(), app) except Exception as e: raise ApplicationError( "crossbar.error.invalid_configuration", "could not instantiate WSGI resource: {}".format(e)) else: ## create a root resource serving everything via WSGI root = WSGIRootResource(wsgi_resource, {}) ## Redirecting root resource ## elif root_type == 'redirect': redirect_url = root_config['url'].encode('ascii', 'ignore') root = RedirectResource(redirect_url) ## Pusher resource ## elif root_type == 'pusher': ## create a vanilla session: the pusher will use this to inject events ## pusher_session_config = ComponentConfig( realm=root_config['realm'], extra=None) pusher_session = ApplicationSession(pusher_session_config) ## add the pushing session to the router ## self.session_factory.add(pusher_session, authrole=root_config.get( 'role', 'anonymous')) ## now create the pusher Twisted Web resource and add it to resource tree ## root = PusherResource(root_config.get('options', {}), pusher_session) ## Invalid root resource ## else: raise ApplicationError( "crossbar.error.invalid_configuration", "invalid Web root path type '{}'".format(root_type)) ## create Twisted Web resources on all non-root paths configured ## self.add_paths(root, config.get('paths', {})) ## create the actual transport factory ## transport_factory = Site(root) transport_factory.noisy = False ## Web access logging ## if not options.get('access_log', False): transport_factory.log = lambda _: None ## Traceback rendering ## transport_factory.displayTracebacks = options.get( 'display_tracebacks', False) ## HSTS ## if options.get('hsts', False): if 'tls' in config['endpoint']: hsts_max_age = int(options.get('hsts_max_age', 31536000)) transport_factory.requestFactory = createHSTSRequestFactory( transport_factory.requestFactory, hsts_max_age) else: log.msg( "Warning: HSTS requested, but running on non-TLS - skipping HSTS" ) ## enable Hixie-76 on Twisted Web ## if options.get('hixie76_aware', False): transport_factory.protocol = HTTPChannelHixie76Aware # needed if Hixie76 is to be supported ## Unknown transport type ## else: ## should not arrive here, since we did check_transport() in the beginning raise Exception("logic error") ## create transport endpoint / listening port from transport factory ## d = create_listening_port_from_config(config['endpoint'], transport_factory, self.config.extra.cbdir, reactor) def ok(port): self.transports[id] = RouterTransport(id, config, transport_factory, port) if self.debug: log.msg( "Router transport '{}'' started and listening".format(id)) return def fail(err): emsg = "ERROR: cannot listen on transport endpoint ({})".format( err.value) log.msg(emsg) raise ApplicationError("crossbar.error.cannot_listen", emsg) d.addCallbacks(ok, fail) return d
def start_router_transport(self, id, config, details=None): """ Start a transport on this router and return when the transport has started. **Usage:** This procedure is registered under * ``crossbar.node.<node_id>.worker.<worker_id>.start_router_transport`` The procedure takes a WAMP transport configuration with a listening endpoint, e.g. .. code-block:: javascript { "type": "websocket", "endpoint": { "type": "tcp", "port": 8080 } } **Errors:** The procedure may raise the following errors: * ``crossbar.error.invalid_configuration`` - the provided transport configuration is invalid * ``crossbar.error.already_running`` - a transport with the given ID is already running (or starting) * ``crossbar.error.cannot_listen`` - could not listen on the configured listening endpoint of the transport * ``crossbar.error.class_import_failed`` - a side-by-side component could not be instantiated **Events:** The procedure will publish an event when the transport **is starting** to * ``crossbar.node.<node_id>.worker.<worker_id>.on_router_transport_starting`` and publish an event when the transport **has started** to * ``crossbar.node.<node_id>.worker.<worker_id>.on_router_transport_started`` :param id: The ID of the transport to start. :type id: unicode :param config: The transport configuration. :type config: dict """ self.log.debug("{}.start_router_transport".format(self.__class__.__name__), id=id, config=config) # prohibit starting a transport twice # if id in self.transports: emsg = "Could not start transport: a transport with ID '{}' is already running (or starting)".format(id) self.log.error(emsg) raise ApplicationError(u'crossbar.error.already_running', emsg) # check configuration # try: checkconfig.check_router_transport(config) except Exception as e: emsg = "Invalid router transport configuration: {}".format(e) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) else: self.log.debug("Starting {}-transport on router.".format(config['type'])) # standalone WAMP-RawSocket transport # if config['type'] == 'rawsocket': transport_factory = WampRawSocketServerFactory(self._router_session_factory, config) transport_factory.noisy = False # standalone WAMP-WebSocket transport # elif config['type'] == 'websocket': transport_factory = WampWebSocketServerFactory(self._router_session_factory, self.config.extra.cbdir, config, self._templates) transport_factory.noisy = False # Flash-policy file server pseudo transport # elif config['type'] == 'flashpolicy': transport_factory = FlashPolicyFactory(config.get('allowed_domain', None), config.get('allowed_ports', None)) # WebSocket testee pseudo transport # elif config['type'] == 'websocket.testee': transport_factory = WebSocketTesteeServerFactory(config, self._templates) # Stream testee pseudo transport # elif config['type'] == 'stream.testee': transport_factory = StreamTesteeServerFactory() # Twisted Web based transport # elif config['type'] == 'web': options = config.get('options', {}) # create Twisted Web root resource # root_config = config['paths']['/'] root_type = root_config['type'] root_options = root_config.get('options', {}) # Static file hierarchy root resource # if root_type == 'static': if 'directory' in root_config: root_dir = os.path.abspath(os.path.join(self.config.extra.cbdir, root_config['directory'])) elif 'package' in root_config: if 'resource' not in root_config: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing resource") try: mod = importlib.import_module(root_config['package']) except ImportError as e: emsg = "Could not import resource {} from package {}: {}".format(root_config['resource'], root_config['package'], e) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) else: try: root_dir = os.path.abspath(pkg_resources.resource_filename(root_config['package'], root_config['resource'])) except Exception as e: emsg = "Could not import resource {} from package {}: {}".format(root_config['resource'], root_config['package'], e) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) else: mod_version = getattr(mod, '__version__', '?.?.?') self.log.info("Loaded static Web resource '{}' from package '{} {}' (filesystem path {})".format(root_config['resource'], root_config['package'], mod_version, root_dir)) else: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing web spec") root_dir = root_dir.encode('ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 self.log.debug("Starting Web service at root directory {}".format(root_dir)) # create resource for file system hierarchy # if root_options.get('enable_directory_listing', False): static_resource_class = StaticResource else: static_resource_class = StaticResourceNoListing cache_timeout = root_options.get('cache_timeout', DEFAULT_CACHE_TIMEOUT) root = static_resource_class(root_dir, cache_timeout=cache_timeout) # set extra MIME types # root.contentTypes.update(EXTRA_MIME_TYPES) if 'mime_types' in root_options: root.contentTypes.update(root_options['mime_types']) patchFileContentTypes(root) # render 404 page on any concrete path not found # root.childNotFound = Resource404(self._templates, root_dir) # WSGI root resource # elif root_type == 'wsgi': if not _HAS_WSGI: raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI unsupported") # wsgi_options = root_config.get('options', {}) if 'module' not in root_config: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app module") if 'object' not in root_config: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app object") # import WSGI app module and object mod_name = root_config['module'] try: mod = importlib.import_module(mod_name) except ImportError as e: raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI app module '{}' import failed: {} - Python search path was {}".format(mod_name, e, sys.path)) else: obj_name = root_config['object'] if obj_name not in mod.__dict__: raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI app object '{}' not in module '{}'".format(obj_name, mod_name)) else: app = getattr(mod, obj_name) # create a Twisted Web WSGI resource from the user's WSGI application object try: wsgi_resource = WSGIResource(self._reactor, self._reactor.getThreadPool(), app) except Exception as e: raise ApplicationError(u"crossbar.error.invalid_configuration", "could not instantiate WSGI resource: {}".format(e)) else: # create a root resource serving everything via WSGI root = WSGIRootResource(wsgi_resource, {}) # Redirecting root resource # elif root_type == 'redirect': redirect_url = root_config['url'].encode('ascii', 'ignore') root = RedirectResource(redirect_url) # Publisher resource (part of REST-bridge) # elif root_type == 'publisher': # create a vanilla session: the publisher will use this to inject events # publisher_session_config = ComponentConfig(realm=root_config['realm'], extra=None) publisher_session = ApplicationSession(publisher_session_config) # add the publishing session to the router # self._router_session_factory.add(publisher_session, authrole=root_config.get('role', 'anonymous')) # now create the publisher Twisted Web resource and add it to resource tree # root = PublisherResource(root_config.get('options', {}), publisher_session) # Webhook resource (part of REST-bridge) # elif root_type == 'webhook': # create a vanilla session: the webhook will use this to inject events # webhook_session_config = ComponentConfig(realm=root_config['realm'], extra=None) webhook_session = ApplicationSession(webhook_session_config) # add the publishing session to the router # self._router_session_factory.add(webhook_session, authrole=root_config.get('role', 'anonymous')) # now create the webhook Twisted Web resource and add it to resource tree # root = WebhookResource(root_config.get('options', {}), webhook_session) # Caller resource (part of REST-bridge) # elif root_type == 'caller': # create a vanilla session: the caller will use this to inject calls # caller_session_config = ComponentConfig(realm=root_config['realm'], extra=None) caller_session = ApplicationSession(caller_session_config) # add the calling session to the router # self._router_session_factory.add(caller_session, authrole=root_config.get('role', 'anonymous')) # now create the caller Twisted Web resource and add it to resource tree # root = CallerResource(root_config.get('options', {}), caller_session) # Generic Twisted Web resource # elif root_type == 'resource': try: klassname = root_config['classname'] self.log.debug("Starting class '{}'".format(klassname)) c = klassname.split('.') module_name, klass_name = '.'.join(c[:-1]), c[-1] module = importlib.import_module(module_name) make = getattr(module, klass_name) root = make(root_config.get('extra', {})) except Exception as e: emsg = "Failed to import class '{}' - {}".format(klassname, e) self.log.error(emsg) self.log.error("PYTHONPATH: {pythonpath}", pythonpath=sys.path) raise ApplicationError(u"crossbar.error.class_import_failed", emsg) # Invalid root resource # else: raise ApplicationError(u"crossbar.error.invalid_configuration", "invalid Web root path type '{}'".format(root_type)) # create Twisted Web resources on all non-root paths configured # self.add_paths(root, config.get('paths', {})) # create the actual transport factory # transport_factory = Site(root) transport_factory.noisy = False # Web access logging # if not options.get('access_log', False): transport_factory.log = lambda _: None # Traceback rendering # transport_factory.displayTracebacks = options.get('display_tracebacks', False) # HSTS # if options.get('hsts', False): if 'tls' in config['endpoint']: hsts_max_age = int(options.get('hsts_max_age', 31536000)) transport_factory.requestFactory = createHSTSRequestFactory(transport_factory.requestFactory, hsts_max_age) else: self.log.warn("Warning: HSTS requested, but running on non-TLS - skipping HSTS") # Unknown transport type # else: # should not arrive here, since we did check_transport() in the beginning raise Exception("logic error") # create transport endpoint / listening port from transport factory # d = create_listening_port_from_config(config['endpoint'], transport_factory, self.config.extra.cbdir, self._reactor) def ok(port): self.transports[id] = RouterTransport(id, config, transport_factory, port) self.log.debug("Router transport '{}'' started and listening".format(id)) return def fail(err): emsg = "Cannot listen on transport endpoint: {}".format(err.value) self.log.error(emsg) raise ApplicationError(u"crossbar.error.cannot_listen", emsg) d.addCallbacks(ok, fail) return d
def _create_resource(self, path_config, nested=True): """ Creates child resource to be added to the parent. :param path_config: Configuration for the new child resource. :type path_config: dict :returns: Resource -- the new child resource """ # WAMP-WebSocket resource # if path_config['type'] == 'websocket': ws_factory = WampWebSocketServerFactory( self._router_session_factory, self.config.extra.cbdir, path_config, self._templates) # FIXME: Site.start/stopFactory should start/stop factories wrapped as Resources ws_factory.startFactory() return WebSocketResource(ws_factory) # Static file hierarchy resource # elif path_config['type'] == 'static': static_options = path_config.get('options', {}) if 'directory' in path_config: static_dir = os.path.abspath( os.path.join(self.config.extra.cbdir, path_config['directory'])) elif 'package' in path_config: if 'resource' not in path_config: raise ApplicationError( u"crossbar.error.invalid_configuration", "missing resource") try: mod = importlib.import_module(path_config['package']) except ImportError as e: emsg = "Could not import resource {} from package {}: {}".format( path_config['resource'], path_config['package'], e) self.log.error(emsg) raise ApplicationError( u"crossbar.error.invalid_configuration", emsg) else: try: static_dir = os.path.abspath( pkg_resources.resource_filename( path_config['package'], path_config['resource'])) except Exception as e: emsg = "Could not import resource {} from package {}: {}".format( path_config['resource'], path_config['package'], e) self.log.error(emsg) raise ApplicationError( u"crossbar.error.invalid_configuration", emsg) else: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing web spec") static_dir = static_dir.encode( 'ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 # create resource for file system hierarchy # if static_options.get('enable_directory_listing', False): static_resource_class = StaticResource else: static_resource_class = StaticResourceNoListing cache_timeout = static_options.get('cache_timeout', DEFAULT_CACHE_TIMEOUT) static_resource = static_resource_class( static_dir, cache_timeout=cache_timeout) # set extra MIME types # static_resource.contentTypes.update(EXTRA_MIME_TYPES) if 'mime_types' in static_options: static_resource.contentTypes.update( static_options['mime_types']) patchFileContentTypes(static_resource) # render 404 page on any concrete path not found # static_resource.childNotFound = Resource404( self._templates, static_dir) return static_resource # WSGI resource # elif path_config['type'] == 'wsgi': if not _HAS_WSGI: raise ApplicationError(u"crossbar.error.invalid_configuration", "WSGI unsupported") if 'module' not in path_config: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app module") if 'object' not in path_config: raise ApplicationError(u"crossbar.error.invalid_configuration", "missing WSGI app object") # import WSGI app module and object mod_name = path_config['module'] try: mod = importlib.import_module(mod_name) except ImportError as e: raise ApplicationError( u"crossbar.error.invalid_configuration", "WSGI app module '{}' import failed: {} - Python search path was {}" .format(mod_name, e, sys.path)) else: obj_name = path_config['object'] if obj_name not in mod.__dict__: raise ApplicationError( u"crossbar.error.invalid_configuration", "WSGI app object '{}' not in module '{}'".format( obj_name, mod_name)) else: app = getattr(mod, obj_name) # Create a threadpool for running the WSGI requests in pool = ThreadPool(maxthreads=path_config.get("maxthreads", 20), minthreads=path_config.get("minthreads", 0), name="crossbar_wsgi_threadpool") self._reactor.addSystemEventTrigger('before', 'shutdown', pool.stop) pool.start() # Create a Twisted Web WSGI resource from the user's WSGI application object try: wsgi_resource = WSGIResource(self._reactor, pool, app) if not nested: wsgi_resource = WSGIRootResource(wsgi_resource, {}) except Exception as e: raise ApplicationError( u"crossbar.error.invalid_configuration", "could not instantiate WSGI resource: {}".format(e)) else: return wsgi_resource # Redirecting resource # elif path_config['type'] == 'redirect': redirect_url = path_config['url'].encode('ascii', 'ignore') return RedirectResource(redirect_url) # JSON value resource # elif path_config['type'] == 'json': value = path_config['value'] return JsonResource(value) # CGI script resource # elif path_config['type'] == 'cgi': cgi_processor = path_config['processor'] cgi_directory = os.path.abspath( os.path.join(self.config.extra.cbdir, path_config['directory'])) cgi_directory = cgi_directory.encode( 'ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 return CgiDirectory(cgi_directory, cgi_processor, Resource404(self._templates, cgi_directory)) # WAMP-Longpoll transport resource # elif path_config['type'] == 'longpoll': path_options = path_config.get('options', {}) lp_resource = WampLongPollResource( self._router_session_factory, timeout=path_options.get('request_timeout', 10), killAfter=path_options.get('session_timeout', 30), queueLimitBytes=path_options.get('queue_limit_bytes', 128 * 1024), queueLimitMessages=path_options.get('queue_limit_messages', 100), debug_transport_id=path_options.get('debug_transport_id', None)) lp_resource._templates = self._templates return lp_resource # Publisher resource (part of REST-bridge) # elif path_config['type'] == 'publisher': # create a vanilla session: the publisher will use this to inject events # publisher_session_config = ComponentConfig( realm=path_config['realm'], extra=None) publisher_session = ApplicationSession(publisher_session_config) # add the publisher session to the router # self._router_session_factory.add(publisher_session, authrole=path_config.get( 'role', 'anonymous')) # now create the publisher Twisted Web resource # return PublisherResource(path_config.get('options', {}), publisher_session) # Webhook resource (part of REST-bridge) # elif path_config['type'] == 'webhook': # create a vanilla session: the webhook will use this to inject events # webhook_session_config = ComponentConfig( realm=path_config['realm'], extra=None) webhook_session = ApplicationSession(webhook_session_config) # add the webhook session to the router # self._router_session_factory.add(webhook_session, authrole=path_config.get( 'role', 'anonymous')) # now create the webhook Twisted Web resource # return WebhookResource(path_config.get('options', {}), webhook_session) # Caller resource (part of REST-bridge) # elif path_config['type'] == 'caller': # create a vanilla session: the caller will use this to inject calls # caller_session_config = ComponentConfig(realm=path_config['realm'], extra=None) caller_session = ApplicationSession(caller_session_config) # add the calling session to the router # self._router_session_factory.add(caller_session, authrole=path_config.get( 'role', 'anonymous')) # now create the caller Twisted Web resource # return CallerResource(path_config.get('options', {}), caller_session) # File Upload resource # elif path_config['type'] == 'upload': upload_directory = os.path.abspath( os.path.join(self.config.extra.cbdir, path_config['directory'])) upload_directory = upload_directory.encode( 'ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 if not os.path.isdir(upload_directory): emsg = "configured upload directory '{}' in file upload resource isn't a directory".format( upload_directory) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) if 'temp_directory' in path_config: temp_directory = os.path.abspath( os.path.join(self.config.extra.cbdir, path_config['temp_directory'])) temp_directory = temp_directory.encode( 'ascii', 'ignore') # http://stackoverflow.com/a/20433918/884770 else: temp_directory = os.path.abspath(tempfile.gettempdir()) temp_directory = os.path.join(temp_directory, 'crossbar-uploads') if not os.path.exists(temp_directory): os.makedirs(temp_directory) if not os.path.isdir(temp_directory): emsg = "configured temp directory '{}' in file upload resource isn't a directory".format( temp_directory) self.log.error(emsg) raise ApplicationError(u"crossbar.error.invalid_configuration", emsg) # file upload progress and finish events are published via this session # upload_session_config = ComponentConfig(realm=path_config['realm'], extra=None) upload_session = ApplicationSession(upload_session_config) self._router_session_factory.add(upload_session, authrole=path_config.get( 'role', 'anonymous')) self.log.info( "File upload resource started. Uploads to {upl} using temp folder {tmp}.", upl=upload_directory, tmp=temp_directory) return FileUploadResource(upload_directory, temp_directory, path_config['form_fields'], upload_session, path_config.get('options', {})) # Generic Twisted Web resource # elif path_config['type'] == 'resource': try: klassname = path_config['classname'] self.log.debug("Starting class '{}'".format(klassname)) c = klassname.split('.') module_name, klass_name = '.'.join(c[:-1]), c[-1] module = importlib.import_module(module_name) make = getattr(module, klass_name) return make(path_config.get('extra', {})) except Exception as e: emsg = "Failed to import class '{}' - {}".format(klassname, e) self.log.error(emsg) self.log.error("PYTHONPATH: {pythonpath}", pythonpath=sys.path) raise ApplicationError(u"crossbar.error.class_import_failed", emsg) # Schema Docs resource # elif path_config['type'] == 'schemadoc': realm = path_config['realm'] if realm not in self.realm_to_id: raise ApplicationError( u"crossbar.error.no_such_object", "No realm with URI '{}' configured".format(realm)) realm_id = self.realm_to_id[realm] realm_schemas = self.realms[realm_id].session._schemas return SchemaDocResource(self._templates, realm, realm_schemas) # Nested subpath resource # elif path_config['type'] == 'path': nested_paths = path_config.get('paths', {}) if '/' in nested_paths: nested_resource = self._create_resource(nested_paths['/']) else: nested_resource = Resource404(self._templates, b'') # nest subpaths under the current entry # self._add_paths(nested_resource, nested_paths) return nested_resource else: raise ApplicationError( u"crossbar.error.invalid_configuration", "invalid Web path type '{}' in {} config".format( path_config['type'], 'nested' if nested else 'root'))
root = Resource() root.putChild("shoutboxws", resource) site = Site(root) reactor.listenTCP(12500, site, interface='0.0.0.0') #reactor.listenSSL(12500, site, DefaultOpenSSLContextFactory('/home/shoutbox/keys/privkey1.pem', '/home/shoutbox/keys/fullchain1.pem', SSL.TLSv1_2_METHOD)) reactor.run() else: app = Flask(__name__) # ... flask setup chatstate = ShoutboxTransaction(ShoutboxWSProtocol) # a TransactionManager is used when you might have multiple Transactions which can all be served over the same websocket URI # they're looked up based on a GET parameter in the URL, a unique key for each transaction # # here we use a static transaction, if you wanted to use TransactionManager instead: # # tm = TransactionManager(chatstate) # resource = WebSocketResource('wss://somesite.com/shoutboxws', tm) shoutbox_resource = WebSocketResource('wss://somesite.com/shoutboxws', lambda x: chatstate) resource = WSGIRootResource(WSGIResource(reactor, reactor.getThreadPool(), app), { 'shoutboxws': shoutbox_resource, }) site = Site(resource) reactor.listenTCP(12500, site, interface='0.0.0.0') #reactor.listenSSL(12500, site, DefaultOpenSSLContextFactory('/home/shoutbox/keys/privkey1.pem', '/home/shoutbox/keys/fullchain1.pem', SSL.TLSv1_2_METHOD)) reactor.run()
def _server(self, port=9999, keepalive=True): from .ws_protocol import JsonWSProtocol import web from web.httpserver import StaticMiddleware, StaticApp from autobahn.twisted.websocket import WebSocketServerProtocol, \ WebSocketServerFactory from autobahn.twisted.resource import WebSocketResource, WSGIRootResource from twisted.internet import reactor from twisted.web.server import Site from twisted.web.wsgi import WSGIResource from twisted.python import log from twisted.web.static import File tmux_self = self class TMuxWebServer(web.auto_application): def __init__(self): web.auto_application.__init__(self) self._renderer = web.template.render(path.realpath( path.join(path.dirname(__file__), 'www')), base="base", globals=globals()) self_app = self class Index(self.page): path = '/' def GET(self): tmux_self.load_config() tmux_self.init() ws_uri = '%s://%s%sws' % ( 'ws' if web.ctx['protocol'] == 'http' else 'wss', web.ctx['host'], web.ctx['fullpath']) return self_app._renderer.index( ws_uri, tmux_self.config, tmux_self.known_tags) class Log(self.page): path = '/log' def GET(self): lines = tmux_self.server.cmd('capture-pane', '-p', '-C', '-S', '-100000').stdout return '\n'.join(lines) class TMuxWSProtocol(JsonWSProtocol): def __init__(self): super(TMuxWSProtocol, self).__init__() def on_button(self, payload): debug('button pressed: \n%s' % pformat(payload)) window_name = payload['id'] cmd = payload['cmd'] if cmd == 'launch': if window_name == '': tmux_self.launch_all_windows() else: tmux_self.launch_window(window_name) elif cmd == 'launch-tag': tmux_self.launch_all_windows(tags={window_name}) elif cmd == 'stop': if window_name == '': tmux_self.stop_all_windows() else: tmux_self.stop_window(window_name) elif cmd == 'stop-tag': tmux_self.stop_all_windows(tags={window_name}) elif cmd == 'terminate': tmux_self.kill_all_windows() sleep(1) tmux_self.init() sleep(1) self.sendJSON(self.on_status()) def on_status(self, payload=None): debug('status-requested: ') res = {'windows': {}, 'method': 'update_status'} for w in tmux_self.config['windows']: res['windows'][w['name']] = tmux_self.is_running(w['name']) return res # return {'button_outcome': True} log.startLogging(sys.stdout) wsFactory = WebSocketServerFactory() wsFactory.protocol = TMuxWSProtocol wsResource = WebSocketResource(wsFactory) staticResource = File( path.realpath(path.join(path.dirname(__file__), 'www/static'))) app = TMuxWebServer() # create a Twisted Web WSGI resource for our Flask server wsgiResource = WSGIResource(reactor, reactor.getThreadPool(), app.wsgifunc()) # create a root resource serving everything via WSGI/Flask, but # the path "/ws" served by our WebSocket stuff rootResource = WSGIRootResource(wsgiResource, { b'ws': wsResource, b'static': staticResource }) # create a Twisted Web Site and run everything site = Site(rootResource) reactor.listenTCP(port, site) reactor.run() # kill everything when server dies if not keepalive: self.kill_all_windows()
from twisted.web.wsgi import WSGIResource from twisted.web.server import Site from autobahn.twisted.resource import WSGIRootResource from twisted.internet import reactor import compilation_site import game_connector import config if __name__ == '__main__': compilation_site.app.debug = True wsgi_app = WSGIResource(reactor, reactor.getThreadPool(), compilation_site.app) root = WSGIRootResource(wsgi_app, {'game_': game_connector.game_resource}) reactor.listenTCP(config.PORT, Site(root)) reactor.run()