本项目实现了任务执行的实时进度查询

实现方式

前端websocket + 后端websocket + 后端redis订阅/发布

实现原理

任务执行后,假设用变量num标记任务执行的进度,然后将num发布为订阅的消息保存到redis队列,比如 redis_helper.public('当前任务进度为 %s' %num),django的websocket视图在特定频道订阅消息num并利用websocket协议将消息实时推送到前端,完成前端实时进度展示。

实现代码

redis订阅/发布:

class RedisHelper:
def __init__(self, key):
self.__conn = redis.Redis(host=config.host2, port=config.port2, db=config.db2)
self.chan_sub = key
self.chan_pub= key #发送消息
def public(self,msg):
# logger.info(msg)
self.__conn.publish(self.chan_pub,msg)
return True
#订阅
def subscribe(self):
#打开收音机
pub = self.__conn.pubsub()
#调频道
pub.subscribe(self.chan_sub)
#准备接收
pub.parse_response()
return pub

django视图:

@accept_websocket
def analyze(request):
if not request.is_websocket(): # 判断是不是websocket连接
file_path=request.GET.get('file_path')
file_path_id = request.GET.get('file_path_id')
file=File.objects.get_or_create(id=file_path_id)[0]
jobname=file.name
job = Job(name=jobname,file=file)
job.save()
channel = job.id
result = cluster_analyze_task.delay(channel,file_path,file_path_id)
taskid=result.id
job.task_id=taskid
job.save()
return JsonResponse({'taskid': taskid,'channel': channel},safe=False)
else:
for message in request.websocket:
obj = RedisHelper(message)
redis_sub = obj.subscribe() while True:
msg = redis_sub.parse_response()
msg = msg[2]
request.websocket.send(msg) # 发送消息到客户端
if msg.decode()=='end':
break

前端websocket:

vue的method中增加如下方法:
initWebSocket() { // 初始化weosocket
// ws地址
const wsuri = 'ws://10.39.211.151:8000/app/analyze/';
this.websock = new WebSocket(wsuri);
this.websock.onopen = this.websocketonopen;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
},
websocketonmessage(e) { // 数据接收
// console.log(e.data);
},
websocketsend(agentData) { // 数据发送
// 若是ws开启状态
if (this.websock.readyState === this.websock.OPEN) {
this.websock.send(agentData)
}
// 若是 正在开启状态,则等待300毫秒
else if (this.websock.readyState === this.websock.CONNECTING) {
let that = this;// 保存当前对象this
setTimeout(function() {
that.websock.send(agentData)
}, 300);
}
// 若未开启 ,则等待500毫秒
else {
this.initWebSocket();
let that = this;// 保存当前对象this
setTimeout(function() {
that.websock.send(agentData)
}, 500);
}
},
websocketonopen() {
// alert('数据发送中...');
console.log('WebSocket连接成功');
},
websocketclose(e) { // 关闭
console.log('connection closed (' + e.code + ')');
} 在创建时进行初始化
created() {
this.initWebSocket();
},

效果图

从零开始搭建django前后端分离项目 系列四(实战之实时进度)的更多相关文章

  1. 从零开始搭建django前后端分离项目 系列一(技术选型)

    前言 最近公司要求基于公司的hadoop平台做一个关于电信移动网络的数据分析平台,整个项目需求大体分为四大功能模块:数据挖掘分析.报表数据查询.GIS地理化展示.任务监控管理.由于页面功能较复杂,所以 ...

  2. 从零开始搭建django前后端分离项目 系列三(实战之异步任务执行)

    前面已经将项目环境搭建好了,下面进入实战环节.这里挑选项目中涉及到的几个重要的功能模块进行讲解. celery执行异步任务和任务管理 Celery 是一个专注于实时处理和任务调度的分布式任务队列.由于 ...

  3. 从零开始搭建django前后端分离项目 系列二(项目搭建)

    在开始项目之前,假设你已了解以下知识:webpack配置.vue.js.django.这里不会教你webpack的基本配置.热更新是什么,也不会告诉你如何开始一个django项目,有需求的请百度,相关 ...

  4. 从零开始搭建django前后端分离项目 系列六(实战之聚类分析)

    项目需求 本项目从impala获取到的数据为用户地理位置数据,每小时的数据量大概在8000万条,数据格式如下: 公司要求对这些用户按照聚集程度进行划分,将300米范围内用户数大于200的用户划分为一个 ...

  5. 从零开始搭建django前后端分离项目 系列五(实战之excel流式导出)

    项目中有一处功能需求是:需要在历史数据查询页面进行查询字段的选择,然后由后台数据库动态生成对应的excel表格并下载到本地. 如果文件较小,解决办法是先将要传送的内容全生成在内存中,然后再一次性传入R ...

  6. Django前后端分离项目部署

    vue+drf的前后端分离部署笔记 前端部署过程 端口划分: vue+nginx的端口 是81 vue向后台发请求,首先发给的是代理服务器,这里模拟是nginx的 9000 drf后台运行在 9005 ...

  7. luffy项目搭建流程(Django前后端分离项目范本)

    第一阶段: 1.版本控制器:Git      2.pip安装源换国内源    3.虚拟环境搭建        4.后台:Django项目创建 5.数据库配置              6.luffy前 ...

  8. nginx+vue+uwsgi+django的前后端分离项目部署

    Vue+Django前后端分离项目部署,nginx默认端口80,数据提交监听端口9000,反向代理(uwsgi配置)端口9999 1.下载项目文件(统一在/opt/luffyproject目录) (1 ...

  9. List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac

    List多个字段标识过滤 class Program{  public static void Main(string[] args) { List<T> list = new List& ...

随机推荐

  1. 自定义View的三个构造函数

    自定义View有三个构造方法,它们的作用是不同的. public MyView(Context context) { super(context); } public MyView(Context c ...

  2. Android ScrollView内部组件设置android:layout_height="fill_parent"无效的解决办法

    问题:scrollview内部组件都设置了android:layout_height="fill_parent"却没有效果. 解决办法:设置scrollview的fillViewp ...

  3. js的深层克隆和浅层克隆代码和理解

    <script> //判断是不是原始值 //判断是数组还是对象 //建立相应的数组或对象 var obj={ name:'辣鸡', sex:'male', card:['laobi','f ...

  4. Python lambda介绍

    转自:http://www.cnblogs.com/evening/archive/2010/03/29/2423554.html Python lambda 介绍   在学习python的过程中,l ...

  5. Elixir 单元测试

    概述 elixir 中自带了单元测试框架 ExUnit ,其中提供单元测试的一系列,主要包含以下模块: ExUnit: 单元测试框架 ExUnit.Assertions: 断言 ExUnit.Case ...

  6. 《Java大学教程》—第9章 软件质量

    软件质量:可维护性.可靠性.健壮性.可用性. 9.3 可维护性系统维护(maintaining)是指根据需求的变化更新现有系统的过程 9.3.1    封装的重要性连锁反应:对系统某一部分的改变可能会 ...

  7. 【Linux常见问题】SecureCRT 终端连接密钥交换失败错误

    SecureCRT 终端软件连接linux操作系统,出现如下错误: 英文描述:Key exchange failed. No compatible key exchange method. The s ...

  8. Java面试知识点之计算机网络篇(一)

    前言:在Java面试中,计算机网络的知识也是一项重点,因此笔者在此对计算机网络的相关知识进行总结. 1.OSI参考模型 自下而上:物理层(物理介质,比特流).数据链路层(网卡.交换机).网络层(IP协 ...

  9. xpath 解析 及案例

    xpath解析 编码流程: 1.实例化一个etree对象,且将页面源码加载到该对象中 2.使用xpath函数,且在函数中必须作用一个xpath表达式进行标签的定位 3.使用xpath进行属性和文本的提 ...

  10. 安利一个_Java学习笔记总结

    javaIO 字符编码 多线程 线程池 ArrayList遍历方式 LinkedList遍历方式 Vector遍历方式 Vector, ArrayList, LinkedList 的区别是什么? Ha ...