最近想在TODO项目(django)上加一个实时更新TODO动态的功能,这样感觉更酷炫。。查阅了一下一般有以下解决方案:
用Ajax定时发请求。比如每隔1分钟通过Ajax发送一个数据库查询请求,看看有没新的item被save。这个是最直接最简单的做法,但是做不到实时更新,而且很耗费server的资源。
集成WebSocket通信的解决方案。WebSocket是双工通道的通信协议,而django等python框架用的WSGI的同步协议,所以需要起建立另一个支持WebSocket的server去handle实时通信的需求,最近大热的nodejs/socketio就可以支持WebSocket的服务,于是有就有大牛写了一个集成socketio的django插件django-socketio-> 链接。它把socketio以app的形式集成进了django,于是大家可以愉快地用django建立聊天室了。但是,我的项目里面已经有大量的Ajax的方法与WebSocket不兼容,而且socketio对于关系型数据库的操作不是特别好。所以它并不是一个好的方案。忍痛割爱~
Comet:Long-polling(长轮询)。这个是目前主流的方案。建立一个定时长连接,一旦server端有更新立刻返回。socketio也支持这种模式,它在不支持WebSocket的情况下使用Long-polling进行实时通信。好,就玩一玩它把~
装包
Follow大牛的github,所有的依赖包都可以在pipy里面找到并用pip进行安装。
但是小心,里面有坑。不是所有的版本都可以正常工作的,而且装django-socketio的时候会把你老的django版本卸载了然后重新装上最新版django 1.8,导致你原有的code无法工作(API都变了)。下面是我目前装的依赖包版本,可以正常工作:
集成代码
将socketio塞进app列表
将socketio模板塞进HTML head
在你的client端js代码中启动socket,并建立名为‘notification’的通信连接通道(channel)。countNewMessage方法在server返回数据时候调用。send的方法发送id为1的JSON到server端。
在server端view中新建socket处理方法。on_message的语法糖是bind event with channel,broadcast方法将id发给每个client端。
启动server
这里需要启动两个不同端口的server,一个django的,一个socketio的。
打开多个demo,会发现先打开的console log记录了1。更多的细节可以参考大牛的demo或者是我的github code:)