1. 程式人生 > >基於輪詢實現實時的在線投票系統

基於輪詢實現實時的在線投票系統

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;
        }
    
</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>
templates/user_list.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

基於輪詢實現實時的在線投票系統