def inner_run(self, *args, **options): # Check a handler is registered for http reqs; if not, add default one self.channel_layer = channel_layers[DEFAULT_CHANNEL_LAYER] self.channel_layer.router.check_default(http_consumer=ViewConsumer(), ) self.addr = self.get_addr(options['addr']) self.port = self.get_port(options['port']) # Run checks self.stdout.write("Performing system checks...\n\n") self.check(display_num_errors=True) self.check_migrations() # Print helpful text quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C' self.stdout.write( ( "\n" "otree-core version %(otree_version)s, " "Django version %(django_version)s, " "using settings %(settings)r\n" "Starting web server at http://%(addr)s:%(port)s/\n" # "Channel layer %(layer)s\n" "Quit the server with %(quit_command)s.\n") % { "django_version": self.get_version(), "otree_version": otree.__version__, "settings": settings.SETTINGS_MODULE, "addr": '[%s]' % self.addr if self._raw_ipv6 else self.addr, "port": self.port, "quit_command": quit_command, "layer": self.channel_layer, }) self.stdout.flush() # Launch server in 'main' thread. Signals are disabled as it's still # actually a subthread under the autoreloader. self.logger.debug("Daphne running, listening on %s:%s", self.addr, self.port) manager = Manager() daphne_cmd = 'daphne otree.asgi:channel_layer -b {} -p {}'.format( self.addr, self.port) print(daphne_cmd) manager.add_process('daphne', daphne_cmd, env=self.get_env(options)) for i in range(3): manager.add_process('worker{}'.format(i), 'otree runworker', env=self.get_env(options)) manager.loop() sys.exit(manager.returncode)
def get_consumer(self, *args, **options): """ Returns the static files serving handler wrapping the default handler, if static files should be served. Otherwise just returns the default handler. """ use_static_handler = options.get('use_static_handler', True) insecure_serving = options.get('insecure_serving', False) if use_static_handler and (settings.DEBUG or insecure_serving): return StaticFilesConsumer() else: return ViewConsumer()
def inner_run(self, *args, **options): # Check a handler is registered for http reqs; if not, add default one self.channel_layer = channel_layers[DEFAULT_CHANNEL_LAYER] if not self.channel_layer.registry.consumer_for_channel( "http.request"): self.channel_layer.registry.add_consumer(ViewConsumer(), ["http.request"]) # Note that this is the channel-enabled one on the console self.logger.info("Worker thread running, channels enabled") # Launch a worker thread worker = WorkerThread(self.channel_layer) worker.daemon = True worker.start() # Launch server in main thread from daphne.server import Server Server( channel_layer=self.channel_layer, host=self.addr, port=int(self.port), ).run()
def handle(self, *args, **options): # Get the backend to use self.verbosity = options.get("verbosity", 1) self.logger = setup_logger('django.channels', self.verbosity) channel_layer = channel_layers[DEFAULT_CHANNEL_LAYER] # Check a handler is registered for http reqs if not channel_layer.registry.consumer_for_channel("http.request"): # Register the default one channel_layer.registry.add_consumer(ViewConsumer(), ["http.request"]) # Launch a worker self.logger.info("Running worker against backend %s", channel_layer.alias) # Optionally provide an output callback callback = None if self.verbosity > 1: callback = self.consumer_called # Run the worker try: Worker(channel_layer=channel_layer, callback=callback).run() except KeyboardInterrupt: pass
from django.http import HttpResponse from channels.handler import AsgiHandler, ViewConsumer from channels import Group default_consumer = ViewConsumer() def http_consumer(msg): # hijack if path matches path = msg['path'] if (path.strip(b'/') == b'event'): r = HttpResponse("Well") # open up SSE stream reply = { 'status': 200, 'headers': [ ('Content-Type', 'text/event-stream'), ], # we shall probably setup cache headers right as well 'more_content': True } print("event subscriptions", msg.reply_channel) msg.reply_channel.send(reply) Group('yo').add(msg.reply_channel) # the problem being there's not # disconnect event with SSE, nor with channels # the only way to get this is erroring on sending # data .. else:
from channels.routing import route from channels.handler import ViewConsumer channel_routing = [ route("http.request", ViewConsumer()), ]
# In routing.py from django.conf import settings from channels.routing import route, include from channels.staticfiles import StaticFilesConsumer from channels.handler import ViewConsumer from seiketsu.graphql.routing import channel_routing as graphql_routing channel_routing = [ include(graphql_routing, path="^/graphql"), route("http.request", StaticFilesConsumer()) if settings.DEBUG else route("http.request", ViewConsumer()), ]