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

4

我目前正在开发一款由Django / apache提供服务的HTML5 Web应用程序。

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

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

我在这方面经验很少(我更多地是后端开发人员,所以这对我来说都是新鲜的)。我最初想从Javascript端向服务器发出长时间的HTTP请求:这个请求只有在超时期限之后才会给出结果(在这种情况下,客户端将不得不重试并立即等待),或者在某些内容发生变化后才会回复一些关于需要刷新的模型的信息。

理论上看起来这似乎可行,但我觉得最好先问一下,因为它似乎很常见,如果没有针对这种任务的框架存在,我会感到惊讶。

所以我的问题是:在这种情况下是否有一种事实上的标准/技术可以使用,或者您推荐使用什么来实现它?

服务器在VM上运行,我完全控制该VM:这意味着我可以安装任何我需要实现它的软件。尽可能避免使用多个网络端口,但如果这样做确实更容易,那就没问题。


看一下Websockets,它们可以用于实时事件而无需使用轮询。至于框架,我还没有看到任何与Django集成得很好的漂亮框架。现在JS开发人员似乎只关心NodeJS。 - Rebs
1个回答

4

实时更新可以采用(至少)两种方法:(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项目发送更新,然后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'}))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接