基於輪詢實現實時的在線投票系統
阿新 • • 發佈:2018-10-06
methods inter ces gif lang pos 方法 pre ESS
需求
用戶在投票的頁面可以實時的監測到,投票詳情
在這裏我會通過輪詢和長輪詢(推薦使用這個,可以減少請求數,實時性也好)的方法來實現
基於輪詢實現投票系統
大致的思路是前端開啟一個定時器每隔10秒定時的向服務器獲取投票的結果
from flask import Flask,render_template,request,jsonify app = Flask(__name__) USERS = { ‘1‘:{‘name‘:‘貝貝‘,‘count‘:1}, ‘2‘:{‘name‘:‘小東北‘,‘count‘:0}, ‘3‘:{‘name‘:‘何偉明‘,‘count‘:0}, } @app.route(‘/user/list‘) def user_list(): import time return render_template(‘user_list.html‘,users=USERS) @app.route(‘/vote‘,methods=[‘POST‘]) def vote(): uid = request.form.get(‘uid‘) USERS[uid][‘count‘] += 1 return "投票成功" @app.route(‘/get/vote‘,methods=[‘GET‘]) def get_vote(): return jsonify(USERS) if __name__ == ‘__main__‘: # app.run(host=‘192.168.13.253‘,threaded=True) app.run(threaded=True)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> li{ cursor: pointer; }templates/user_list.html</style> </head> <body> <ul id="userList"> {% for key,val in users.items() %} <li uid="{{key}}">{{val.name}} ({{val.count}})</li> {% endfor %} </ul> <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script> <script> $(function () { $(‘#userList‘).on(‘dblclick‘,‘li‘,function () { var uid = $(this).attr(‘uid‘); $.ajax({ url:‘/vote‘, type:‘POST‘, data:{uid:uid}, success:function (arg) { console.log(arg); } }) }); }); /* 獲取投票信息 */ function get_vote() { $.ajax({ url:‘/get/vote‘, type:"GET", dataType:‘JSON‘, success:function (arg) { $(‘#userList‘).empty(); $.each(arg,function (k,v) { var li = document.createElement(‘li‘); li.setAttribute(‘uid‘,k); li.innerText = v.name + "(" + v.count + ‘)‘ ; $(‘#userList‘).append(li); }) } }) } setInterval(get_vote,3000); </script> </body> </html>
缺點 : 獲取票數的實時性不好,頻繁的向服務器發送請求
基於長輪詢實現投票系統
基本的思路:
前端: 通過遞歸發送查詢投票詳情的請求,更新數據 (數據驅動模型)
服務端 :如果沒有人來投票服務器把所有用戶的請求hang住10秒,把原有的信息返回,如果在這等待的10s中有人來投票,直接返回最新的結果給所有hang住的用戶
基於隊列queue的阻塞, 來實現hang住請求,queue的基本用法如下
import queue q = queue.Queue() val = q.get() print(val) try: val = q.get(timeout=10) print(val) except queue.Empty: pass
run.py
from flask import Flask,render_template,request,jsonify,session import uuid import queue app = Flask(__name__) app.secret_key = ‘asdfasdfasd‘ USERS = { ‘1‘:{‘name‘:‘貝貝‘,‘count‘:1}, ‘2‘:{‘name‘:‘小東北‘,‘count‘:0}, ‘3‘:{‘name‘:‘何偉明‘,‘count‘:0}, } QUEQUE_DICT = { # ‘asdfasdfasdfasdf‘:Queue() } @app.route(‘/user/list‘) def user_list(): user_uuid = str(uuid.uuid4()) QUEQUE_DICT[user_uuid] = queue.Queue() session[‘current_user_uuid‘] = user_uuid return render_template(‘user_list.html‘,users=USERS) @app.route(‘/vote‘,methods=[‘POST‘]) def vote(): uid = request.form.get(‘uid‘) USERS[uid][‘count‘] += 1 for q in QUEQUE_DICT.values(): q.put(USERS) return "投票成功" @app.route(‘/get/vote‘,methods=[‘GET‘]) def get_vote(): user_uuid = session[‘current_user_uuid‘] q = QUEQUE_DICT[user_uuid] ret = {‘status‘:True,‘data‘:None} try: users = q.get(timeout=10) ret[‘data‘] = users except queue.Empty: ret[‘status‘] = False return jsonify(ret) if __name__ == ‘__main__‘: app.run(host=‘192.168.13.253‘,threaded=True) # app.run(threaded=True)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> li{ cursor: pointer; } </style> </head> <body> <ul id="userList"> {% for key,val in users.items() %} <li uid="{{key}}">{{val.name}} ({{val.count}})</li> {% endfor %} </ul> <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script> <script> $(function () { $(‘#userList‘).on(‘click‘,‘li‘,function () { var uid = $(this).attr(‘uid‘); $.ajax({ url:‘/vote‘, type:‘POST‘, data:{uid:uid}, success:function (arg) { console.log(arg); } }) }); get_vote(); }); /* 獲取投票信息 */ function get_vote() { $.ajax({ url:‘/get/vote‘, type:"GET", dataType:‘JSON‘, success:function (arg) { if(arg.status){ $(‘#userList‘).empty(); $.each(arg.data,function (k,v) { var li = document.createElement(‘li‘); li.setAttribute(‘uid‘,k); li.innerText = v.name + "(" + v.count + ‘)‘ ; $(‘#userList‘).append(li); }) } get_vote(); } }) } </script> </body> </html>templates/user_list.html
基於輪詢實現實時的在線投票系統