How can I make SSE with Python (Django)?

删除回忆录丶 提交于 2019-12-01 09:12:50

This is working example from w3schools in Django:

template

<!DOCTYPE html>
<html>
<body>

<h1>Getting server updates</h1>
<div id="result"></div>

<script>
if(typeof(EventSource) !== "undefined") {
  var source = new EventSource("stream/");
  source.onmessage = function(event) {
    document.getElementById("result").innerHTML += event.data + "<br>";
  };
} else {
  document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events...";
}
</script>

</body>
</html>

views

import datetime
from django.http import HttpResponse

def stream(request):
    return HttpResponse(
        'data: The server time is: %s\n\n' % datetime.datetime.now(),
        content_type='text/event-stream'
    )

urls

urlpatterns = [
    path('stream/', views.stream, name='stream')
]

Update:

If you want to manage your notifications you can create the model like:

from django.db import models

class Notification(models.Model):
    text = models.CharField(max_length=200)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    sent = models.BooleanField(default=False)

Then create the view that is looking for the first unsent notification and sends it:

@login_required
def stream(request):
    notification = Notification.objects.filter(
        sent=False, user=request.user
    ).first()

    text = ''

    if notification:
        text = notification.text
        notification.sent = True
        notification.save()

    return HttpResponse(
        'data: %s\n\n' % text,
        content_type='text/event-stream'
    )

And the send_notification function that creates an entry in the Notification model (just call this function from anywhere in your code):

def send_notification(user, text):
    Notification.objects.create(
        user=user, text=text
    )

That's it, simple as that.

After reading this, I think I understood the whole thing (please comment if I’m wrong).



Django does NOT natively support keep-alive connections. 
This means, when the client gets the message from the server, the connection is immediately closed after (like any classic HTTP request/response cycle).


What’s different with text/event-stream request, is that the client automatically tries to reconnect to the server every second (the length can be changed with a retry parameter).



Unfortunately, it seems using SSE in that case has no interest since it has the same con’s that polling (ie. a request/response cycle occurs each X seconds).



As expected and mentioned in other answers, I would need django-channels to create a persistent connection that prevent HTTP request/response overheads and ensure the message is sent immediately.


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!