mirror of
https://github.com/django/daphne.git
synced 2025-10-26 13:31:00 +03:00
54 lines
1.7 KiB
Python
54 lines
1.7 KiB
Python
import functools
|
|
|
|
from django.core.handlers.base import BaseHandler
|
|
from django.http import HttpRequest, HttpResponse
|
|
|
|
from channels import Channel, channel_layers, DEFAULT_CHANNEL_LAYER
|
|
|
|
|
|
class UrlConsumer(object):
|
|
"""
|
|
Dispatches channel HTTP requests into django's URL system.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.handler = BaseHandler()
|
|
self.handler.load_middleware()
|
|
|
|
def __call__(self, **kwargs):
|
|
request = HttpRequest.channel_decode(kwargs)
|
|
try:
|
|
response = self.handler.get_response(request)
|
|
except HttpResponse.ResponseLater:
|
|
return
|
|
Channel(request.response_channel).send(**response.channel_encode())
|
|
|
|
|
|
def view_producer(channel_name):
|
|
"""
|
|
Returns a new view function that actually writes the request to a channel
|
|
and abandons the response (with an exception the Worker will catch)
|
|
"""
|
|
def producing_view(request):
|
|
Channel(channel_name).send(**request.channel_encode())
|
|
raise HttpResponse.ResponseLater()
|
|
return producing_view
|
|
|
|
|
|
def view_consumer(channel_name, alias=None):
|
|
"""
|
|
Decorates a normal Django view to be a channel consumer.
|
|
Does not run any middleware
|
|
"""
|
|
def inner(func):
|
|
@functools.wraps(func)
|
|
def consumer(**kwargs):
|
|
request = HttpRequest.channel_decode(kwargs)
|
|
response = func(request)
|
|
Channel(request.response_channel).send(**response.channel_encode())
|
|
# Get the channel layer and register
|
|
channel_layer = channel_layers[alias or DEFAULT_CHANNEL_LAYER]
|
|
channel_layer.registry.add_consumer(consumer, [channel_name])
|
|
return func
|
|
return inner
|