轮询与长轮询

Posted zh-xiaoyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轮询与长轮询相关的知识,希望对你有一定的参考价值。

一、轮询

前端通过定时器每隔多少秒钟发送一次请求。

投票示例:

app.py

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():
    
    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)

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); //每隔3s中获取一次投票信息

    </script>
</body>
</html>

 

二、长轮询

浏览器发送一次请求过来会让浏览器hang住,最多hang住30s,如果在这一段时间没人发数据让浏览器等30s然后释放,如果在此期间有人发数据了就会立即拿到结果然后返回给用户,实现了结果实时返回,省去了连接的次数。兼容性好、实时、在线

app1.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())                           #用户登录成功的时候为每个人生成一个uuid
    QUEQUE_DICT[user_uuid] = queue.Queue()                  #以uuid为key,为每个人创建一个queue

    session[current_user_uuid] = user_uuid                #把用户的uuid放入session中,session默认放入加密的cookie中
    return render_template(user_list.html,users=USERS)

#投票
@app.route(/vote,methods=[POST])
def vote():
    uid = request.form.get(uid)     #获取用户uid
    USERS[uid][count] += 1          #票数加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]   #去cookie中获取之前放入的uuid
    q = QUEQUE_DICT[user_uuid]                 #根据user_uuid获取q

    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=‘192.168.13.253‘,threaded=True)  #
    app.run(threaded=True)     #

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>

 

以上是关于轮询与长轮询的主要内容,如果未能解决你的问题,请参考以下文章

轮询与长轮询

实时 Web 应用程序的短轮询与长轮询?

ajax轮询与长轮询

扩展聊天应用程序 - 短轮询与长轮询(AJAX、PHP)

WebSockets 与长轮询与 TCP 可扩展性/易用性

轮询长轮询长连接的区别