为 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 的实时视频聊天
如何使用多个发送(请求)实现 HTML5 WEB-Socket