從零開始搭建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();
},

 

效果圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM