Lor*_*ngo 12 python django django-models server-sent-events
我有两个不同的页面,一个 (A) 显示从模型对象中获取的数据,另一个 (B) 更改其字段。我希望当发布数据从 B 发送到服务器时,服务器会更改 A 中的值。最好的方法是什么?
这个例子对我有用,但它是用 PHP 编写的……有没有办法用 Python 复制它? https://www.w3schools.com/html/html5_serversentevents.asp
Iva*_*van 19
这是 Django 中 w3schools 的工作示例:
模板
<!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>
Run Code Online (Sandbox Code Playgroud)
意见
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')
Run Code Online (Sandbox Code Playgroud)
网址
urlpatterns = [
path('stream/', views.stream, name='stream')
]
Run Code Online (Sandbox Code Playgroud)
更新:
如果您想管理您的通知,您可以创建如下模型:
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)
Run Code Online (Sandbox Code Playgroud)
然后创建寻找第一个未发送通知的视图并发送它:
@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')
Run Code Online (Sandbox Code Playgroud)
以及send_notification在Notification模型中创建条目的函数(只需从代码中的任何位置调用此函数):
def send_notification(user, text):
Notification.objects.create(
user=user, text=text
)
Run Code Online (Sandbox Code Playgroud)
就是这样,就这么简单。
看完这篇,我想我明白了整件事(如果我错了,请评论)??
Django 本身不支持保持活动连接。?这意味着,当客户端从服务器获取消息时,连接会立即关闭(就像任何经典的 HTTP 请求/响应循环一样)。
? 与text/event-stream请求不同的是,客户端每秒都会自动尝试重新连接到服务器(长度可以通过retry参数更改)。??
不幸的是,在这种情况下使用 SSE 似乎没有兴趣,因为它与轮询具有相同的缺点(即每 X 秒发生一个请求/响应周期)。
??正如其他答案中所预期和提到的,我需要 django-channels 来创建一个持久连接,以防止 HTTP 请求/响应开销并确保立即发送消息。?
| 归档时间: |
|
| 查看次数: |
13601 次 |
| 最近记录: |