• 从零开始搭建django前后端分离项目 系列四(实战之实时进度)


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

    实现方式

    前端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();
    },

    效果图

  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/dotafeiying/p/9669070.html
Copyright © 2020-2023  润新知