Documentation pour Django 3.1 en dit sur ASYNC Vues:
Les principaux avantages sont la possibilité de servir des centaines de connexions sans utiliser Python======= Ceci vous permet d'utiliser des types de diffusion lente, d'interrogation longue et d'autres types de réponses passionnantes.
Je crois que "streaming lent" signifie que nous pourrions mettre en œuvre un [~ # ~ # ~] SSE [~ # ~] Vue sans monopoliser un fil par client, alors j'ai essayé d'esquisser une vue simple, comme si:
async def stream(request):
async def event_stream():
while True:
yield 'data: The server time is: %s\n\n' % datetime.datetime.now()
await asyncio.sleep(1)
return StreamingHttpResponse(event_stream(), content_type='text/event-stream')
(Remarque: j'ai adapté le code de cette réponse )
Malheureusement, lorsque cette vue est invoquée, elle soulève l'exception suivante:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/asgiref/sync.py", line 330, in thread_handler
raise exc_info[1]
File "/usr/local/lib/python3.7/site-packages/Django/core/handlers/exception.py", line 38, in inner
response = await get_response(request)
File "/usr/local/lib/python3.7/site-packages/Django/core/handlers/base.py", line 231, in _get_response_async
response = await wrapped_callback(request, *callback_args, **callback_kwargs)
File "./chat/views.py", line 144, in watch
return StreamingHttpResponse(event_stream(), content_type='text/event-stream')
File "/usr/local/lib/python3.7/site-packages/Django/http/response.py", line 367, in __init__
self.streaming_content = streaming_content
File "/usr/local/lib/python3.7/site-packages/Django/http/response.py", line 382, in streaming_content
self._set_streaming_content(value)
File "/usr/local/lib/python3.7/site-packages/Django/http/response.py", line 386, in _set_streaming_content
self._iterator = iter(value)
TypeError: 'async_generator' object is not iterable
Pour moi, cela montre que StreamingHttpResponse
_ ne supporte actuellement pas les générateurs ASYNC.
J'ai essayé de modifier StreamingHttpResponse
pour utiliser async for
Mais je n'ai pas pu faire grand chose.
Une idée de la façon dont je pouvais faire ça?
Une autre façon de faire SSE est d'utiliser une bibliothèque spéciale Django-eventstream
:
Ajouter une suite à la page HTML qui consommera des données:
<script src="{% static 'Django_eventstream/eventsource.min.js' %}"></script>
<script src="{% static 'Django_eventstream/reconnecting-eventsource.js' %}"></script>
var es = new ReconnectingEventSource('/events/');
es.addEventListener('message', function (e) {
console.log(e.data);
}, false);
es.addEventListener('stream-reset', function (e) {
// ... client fell behind, reinitialize ...
}, false);
Pour le backend, vous aurez besoin de correctement configurez django , et plus tard, vous pourrez appeler la méthode suivante dans n'importe quelle vue/tâche/signal/méthode nécessaire à l'événement côté serveur (SSE):
Ajouter une vue à la suite qui produira des données (événements):
# from Django_eventstream import send_event
send_event('test', 'message', {'text': 'hello world'})