首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Python (Django)创建SSE?

如何使用Python (Django)创建SSE?
EN

Stack Overflow用户
提问于 2019-01-23 19:44:15
回答 3查看 14.9K关注 0票数 13

我有两个不同的页面,一个(A)显示从模型对象获取的数据,另一个(B)更改其字段。我希望当post数据从B发送到服务器时,服务器会更改A中的值。最好的方法是什么?

这个例子对我来说是可行的,但它是用PHP编写的。有一种方法可以用Python复制它-- https://www.w3schools.com/html/html5_serversentevents.asp

EN

回答 3

Stack Overflow用户

发布于 2019-04-05 02:42:27

这是来自Django的w3schools的工作示例:

模板

代码语言:javascript
复制
<!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>

视图

代码语言:javascript
复制
import datetime
import time
from django.http import StreamingHttpResponse

def stream(request):
    def event_stream():
        while True:
            time.sleep(3)
            yield 'data: The server time is: %s\n\n' % datetime.datetime.now()
    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')

urls

代码语言:javascript
复制
urlpatterns = [
    path('stream/', views.stream, name='stream')
]

更新:

如果你想管理你的通知,你可以创建这样的模型:

代码语言:javascript
复制
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)

然后创建查找第一个未发送通知的视图并发送它:

代码语言:javascript
复制
@login_required
def stream(request):
    def event_stream():
        while True:
            time.sleep(3)
            notification = Notification.objects.filter(
                sent=False, user=request.user
            ).first()

            text = ''

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

            yield 'data: %s\n\n' % text

    return StreamingHttpResponse(event_stream(), content_type='text/event-stream')

以及在Notification模型中创建条目的send_notification函数(只需从代码中的任何位置调用此函数):

代码语言:javascript
复制
def send_notification(user, text):
    Notification.objects.create(
        user=user, text=text
    )

就是这样,就这么简单。

票数 21
EN

Stack Overflow用户

发布于 2019-06-18 08:39:25

在读完this之后,我想我理解了整个事情(如果我错了,请评论).



Django本身并不支持保持连接。
这意味着,当客户端从服务器获得消息时,连接会立即关闭(就像任何经典的HTTP请求/响应周期一样)。

text/event-stream请求的不同之处在于,客户端每秒都会自动尝试重新连接到服务器(长度可以使用retry参数更改).




不幸的是,在这种情况下使用SSE似乎没有任何兴趣,因为它有相同的缺点,即轮询(即。请求/响应周期每X秒发生一次)。

正如预期的和在其他答案中提到的那样,我需要django-来创建持久连接,以防止

请求/响应开销,并确保消息立即发送。

票数 7
EN

Stack Overflow用户

发布于 2021-03-06 09:40:53

正如在其他答案中提到的,您将需要使用Django通道来正确处理异步通信,而不会占用线程。

有关示例,请参阅使用通道实现SSE的the django-eventstream library

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54326515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档