• 从零开始搭建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();
    },

    效果图

  • 相关阅读:
    HDU 1847
    HDU 1717
    KMP未优化模板、
    Codeforces Round #340 (Div. 2) B. Chocolate
    HDU 1042 N!
    HDU 1018 Big Number
    HDU 1031 Design T-Shirt
    解决Windows 7删除执行过的 EXE、Bat文件有延迟的问题
    修改Android手机的“虚拟机堆大小”和android:largeHeap来防止APP内存溢出问题
    Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题
  • 原文地址:https://www.cnblogs.com/dotafeiying/p/9669070.html
Copyright © 2020-2023  润新知