zoukankan      html  css  js  c++  java
  • 从零开始搭建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();
    },

    效果图

  • 相关阅读:
    NoSQL生态系统——hash分片和范围分片两种分片
    NoSQL生态系统——事务机制,行锁,LSM,缓存多次写操作,RWN
    W5500 keep-alive的用途及使用
    APUE学习总结
    Web Socket rfc6455 握 (C++)
    java.nio分析软件包(三)---Charset理解力
    比量iOS6/iOS7, 3.5inch/4.0inch
    【从翻译mos文章】rac数据库,HC_<SID>.dat其他文件Oracle_Home用例下。
    Type mismatch: cannot convert from Enumeration<String> to Enumeration<Object>
    c++宏源证券编程
  • 原文地址:https://www.cnblogs.com/dotafeiying/p/9669070.html
Copyright © 2011-2022 走看看