为 HTML5 Django Web 应用程序实现实时通知系统

Posted

技术标签:

【中文标题】为 HTML5 Django Web 应用程序实现实时通知系统【英文标题】:Implement a real-time notification system for an HTML5 Django web app 【发布时间】:2014-08-20 12:25:46 【问题描述】:

我目前正在开发一个由 Django/apache 提供的 html5 网络应用程序。

该应用程序的目标是监控几个设备:所有客户端逻辑都是用 Angular 编写的,所有数据都来自对后端进行的基于 JSON 的类似 REST 的调用(我认为这很常见)。

到目前为止,这工作得很好。现在我想实现一个通知系统:可以对外部事件做出反应并通知所有正在运行的 web 应用程序实例需要在页面上刷新的东西。我真的不希望所有实例都只轮询服务器,因为这似乎不是最理想的。尤其是在移动设备上,这可能会很快耗尽电池。

我对这类东西的经验很少(我更多的是后端开发人员,所以这对我来说都是全新的)。我首先想到的是从 javascript 端向服务器发出一个长期存在的 HTTP 请求:这个请求只会在超时期限之后给出结果(在这种情况下,客户端必须立即重试并再次等待)或在发生更改后(然后它会回复一些有关需要刷新的模型的信息)。

这在理论上似乎可行,但我想我宁愿先问,因为它看起来很常见,如果不存在此类任务的框架,我会感到惊讶。

所以我的问题是:在这种情况下是否有事实上的标准/技术可以使用和/或你会建议什么来实施它?

服务器在我拥有完全控制权的虚拟机中运行:这意味着我可以安装实现该功能所需的任何软件。我想尽可能避免使用多个网络端口,但如果它使事情变得更容易,那就没问题了。

【问题讨论】:

看看websockets,它们可以用于实时事件而无需使用轮询。至于框架,我还没有看到任何与 django 集成的好框架。 JS 开发者现在似乎只关心 NodeJS。 【参考方案1】:

可以通过(至少)两种方法进行实时更新:(1) 连续轮询,(2) Websocket 协议

我个人最喜欢的是 Websocket 协议(但较旧的浏览器不支持它,因此可能需要在连续或长轮询上进行后备)。 Django (1.9) 目前不支持 WebSocket 协议。所以你的 Django 项目需要一个可以帮助实现 Websocket 协议的助手。常见的选择是Tornado 和 NodeJS。我在下面展示 Tornado 示例:

创建一个辅助 tornado 项目(您可能必须在生产环境中将它托管在不同的服务器上)。在那里你可以有一个WebSocketHandler,如下所示:

import tornado.websocket

# suppose URL for this handler is localhost:8888/my_handler/
class MyWebSocketHandler(tornado.websocket.WebSocketHandler):
    waiters = set()

    def open(self):
        MyWebSocketHandler.waiters.add(self)

    def on_close(self):
        MyWebSocketHandler.waiters.remove(self)

    def on_message(self, message):
        MyWebSocketHandler.send_updates(message)

    @classmethod
    def send_updates(cls, stuff_django_project_sends):
        for waiter in cls.waiters:
            waiter.write_message(stuff_django_project_sends)

在您的 HTML5 应用程序中,您将拥有类似这样的内容(这是纯 JavaScript,我不知道它是 AngularJS 等价物):

var url = "ws://localhost:8888/my_handler/";
socket = new WebSocket(url);  // establish connection with WebSocketHandler to listen to updates
socket.onmessage = function(event) 
    var stuff_django_project_sent = JSON.parse(event.data));
    // do something with this stuff now

现在也在您的 Django 项目中,您将建立与此 WebSocketHandler 的连接。但是在那里您将向 Tornado 项目发送更新,然后该项目将向 HTML5 应用程序发送更新。

首先你必须在 django 中安装 websocket-client 包。然后你会做类似的事情:

from websocket import create_connection
import json

url = "ws://localhost:8888/my_handler/"
web_socket = create_connection(url)
web_socket.send(json.dumps('stuff': 'to send'))

【讨论】:

以上是关于为 HTML5 Django Web 应用程序实现实时通知系统的主要内容,如果未能解决你的问题,请参考以下文章

将fme的模板作为web端的后台计算模型,django实现模板集成

使用 HTML5 websockets 实现基于 web 的实时视频聊天

Django简单应用的实现

如何使用多个发送(请求)实现 HTML5 WEB-Socket

python测试开发django-81.dwebsocket实现websocket

HTML5 - 搭建移动Web应用