ajax並發請求阻塞講解「ajax輪詢請求現實」

輪詢和長輪詢優缺點分析

  1. 輪詢:客戶端定時向伺服器發送Ajax請求,伺服器接到請求後馬上返迴響應信息並關閉連接。優點:後端程序編寫比較容易。缺點:請求中有大半是無用,浪費帶寬和伺服器資源。實例:適於小型應用。
  2. 長輪詢:客戶端向伺服器發送Ajax請求,伺服器接到請求後hold住連接,直到有新消息才返迴響應信息並關閉連接,客戶端處理完響應信息後再向伺服器發送新的請求。優點:在無消息的情況下不會頻繁的請求。缺點:伺服器hold連接會消耗資源。實例:WebQQ、Hi網頁版、Facebook IM。

另外,對於長連接和socket連接也有區分:

  • 長連接:在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連接的請求,伺服器端就能源源不斷地往客戶端輸入數據。
  • 優點:消息即時到達,不發無用請求。
  • 缺點:伺服器維護一個長連接會增加開銷。
  • 實例:Gmail聊天
  • Flash Socket:在頁面中內嵌入一個使用了Socket類的 Flash 程序JavaScript通過調用此Flash程序提供的Socket介面與伺服器端的Socket介面進行通信,JavaScript在收到伺服器端傳送的信息後控制頁面的顯示。
  • 優點:實現真正的即時通信,而不是偽即時。
  • 缺點:客戶端必須安裝Flash插件;非HTTP協議,無法自動穿越防火牆。
  • 實例:網路互動遊戲。

輪詢示例代碼

Flask版

app.py

app.pyfrom 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='127.0.0.1',threaded=True)
    app.run(threaded=True)

templates/user_list.html

<!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>

長輪詢示例代碼

Flask版

app.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=5)
        ret['data'] = users
    except queue.Empty:
        ret['status'] = False

    return jsonify(ret)



if __name__ == '__main__':
    app.run(host='127.0.0.1',threaded=True)
    # app.run(threaded=True)

\templates\user_list.html

<!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>

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/275279.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-17 14:20
下一篇 2024-12-17 14:20

相關推薦

發表回復

登錄後才能評論