mirror of
https://github.com/django/daphne.git
synced 2025-07-14 18:02:17 +03:00
HTTP Long Poll finishing off
This commit is contained in:
parent
4f60726ec4
commit
be1498768f
|
@ -23,10 +23,13 @@ class AsgiRequest(http.HttpRequest):
|
||||||
dict, and wraps request body handling.
|
dict, and wraps request body handling.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Exception that will cause any handler to skip around response
|
|
||||||
# transmission and presume something else will do it later.
|
|
||||||
class ResponseLater(Exception):
|
class ResponseLater(Exception):
|
||||||
pass
|
"""
|
||||||
|
Exception that will cause any handler to skip around response
|
||||||
|
transmission and presume something else will do it later.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
Exception.__init__(self, "Response later")
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
self.message = message
|
self.message = message
|
||||||
|
@ -171,17 +174,37 @@ class AsgiHandler(base.BaseHandler):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
response = http.HttpResponseBadRequest()
|
response = http.HttpResponseBadRequest()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
response = self.get_response(request)
|
||||||
except AsgiRequest.ResponseLater:
|
except AsgiRequest.ResponseLater:
|
||||||
# The view has promised something else
|
# The view has promised something else
|
||||||
# will send a response at a later time
|
# will send a response at a later time
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
response = self.get_response(request)
|
|
||||||
# Transform response into messages, which we yield back to caller
|
# Transform response into messages, which we yield back to caller
|
||||||
for message in self.encode_response(response):
|
for message in self.encode_response(response):
|
||||||
# TODO: file_to_stream
|
# TODO: file_to_stream
|
||||||
yield message
|
yield message
|
||||||
|
|
||||||
|
def process_exception_by_middleware(self, exception, request):
|
||||||
|
"""
|
||||||
|
Catches ResponseLater and re-raises it, else tries to delegate
|
||||||
|
to middleware exception handling.
|
||||||
|
"""
|
||||||
|
if isinstance(exception, AsgiRequest.ResponseLater):
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
return super(AsgiHandler, self).process_exception_by_middleware(exception, request)
|
||||||
|
|
||||||
|
def handle_uncaught_exception(self, request, resolver, exc_info):
|
||||||
|
"""
|
||||||
|
Propagates ResponseLater up into the higher handler method,
|
||||||
|
processes everything else
|
||||||
|
"""
|
||||||
|
if issubclass(exc_info[0], AsgiRequest.ResponseLater):
|
||||||
|
raise
|
||||||
|
return super(AsgiHandler, self).handle_uncaught_exception(request, resolver, exc_info)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def encode_response(cls, response):
|
def encode_response(cls, response):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -25,7 +25,6 @@ class Worker(object):
|
||||||
"""
|
"""
|
||||||
channels = self.channel_layer.registry.all_channel_names()
|
channels = self.channel_layer.registry.all_channel_names()
|
||||||
while True:
|
while True:
|
||||||
logger.debug("Worker waiting for message")
|
|
||||||
channel, content = self.channel_layer.receive_many(channels, block=True)
|
channel, content = self.channel_layer.receive_many(channels, block=True)
|
||||||
logger.debug("Worker got message on %s: repl %s", channel, content.get("reply_channel", "none"))
|
logger.debug("Worker got message on %s: repl %s", channel, content.get("reply_channel", "none"))
|
||||||
# If no message, stall a little to avoid busy-looping then continue
|
# If no message, stall a little to avoid busy-looping then continue
|
||||||
|
|
|
@ -565,6 +565,21 @@ Keys:
|
||||||
server-pushed requests, and applications should not create reply channels.
|
server-pushed requests, and applications should not create reply channels.
|
||||||
|
|
||||||
|
|
||||||
|
Disconnect
|
||||||
|
''''''''''
|
||||||
|
|
||||||
|
Sent when a HTTP connection is closed. This is mainly useful for long-polling,
|
||||||
|
where you may have added the response channel to a Group or other set of
|
||||||
|
channels you want to trigger a reply to when data arrives.
|
||||||
|
|
||||||
|
Channel: ``http.disconnect``
|
||||||
|
|
||||||
|
Keys:
|
||||||
|
|
||||||
|
* ``reply_channel``: Channel name responses would have been sent on. No longer
|
||||||
|
valid after this message is sent; all messages to it will be dropped.
|
||||||
|
|
||||||
|
|
||||||
WebSocket
|
WebSocket
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user