轮询和长轮询优缺点分析
轮询:客户端定期向服务器发送Ajax请求,服务器收到请求后立即返回响应信息并关闭连接。优点:后端编程更容易。缺点:大多数请求都是无用的,浪费了带宽和服务器资源。示例:适合小型应用。
长轮询:客户端向服务器发送Ajax请求,服务器收到请求后保持连接,然后返回响应消息并关闭连接,直到有新消息。客户端在向服务器发送新请求之前处理响应消息。优点:在没有消息的情况下不会频繁请求。缺点:服务器保持连接会消耗资源。例子:网络QQ,嗨网版,脸书即时通讯。
另外,对于长连接和socket连接也有区分:
长连接:在页面中嵌入一个隐藏的iframe,将这个隐藏的iframe的src属性设置为长连接的请求,这样服务器就可以不断地向客户端输入数据。
优点:消息即时到达,无需发送无用的请求。
缺点:服务器保持长连接会增加开销。
示例:Gmail聊天。
Flash Socket:在页面中嵌入一个使用Socket类的Flash程序JavaScript,通过调用这个Flash程序提供的Socket接口与服务器的Socket接口进行通信,JavaScript接收到服务器传输的信息后控制页面的显示。
优点:真正的即时通讯,不是假的即时通讯。
缺点:客户端必须安装Flash插件;不是HTTP协议,无法自动通过防火墙。
例子:网络互动游戏。
轮询示例代码
Flask版
app.py
app.pyfrom flask导入flask,render_template,请求,jsonify
app=Flask(__name__)
用户={ 0
1':{ '姓名' : '路人a ','人数' :1},
2':{ '姓名' : '路人B ','人数' :0},
3':{ '姓名' : '路人C ','人数' :0},
}
@app.route('/user/list ')
def user_list():
导入时间
返回render _ template(' user _ list . html ',users=USERS)
@app.route('/vote ',methods=['POST'])
def投票(:)
uid=request.form.get('uid ')
用户[uid][“计数”]=1
返回“投票成功”
@app.route('/get/vote ',methods=['GET'])
def get_vote():
返回jsonify(USERS)
if __name__=='__main__':
# app.run(主机='127.0.0.1 ',线程=True)
应用程序运行(线程=真)
templates/user_list.html
!DOCTYPE html
html lang='zh-CN '
头
meta charset='UTF-8 '
标题标题/标题
元名称=“视口”内容=“宽度=设备宽度,初始比例=1”
风格
li{
cursor:指针;
}
/style
/head
身体
ul id='userList '
{%对于密钥,val在users.items() %}中
Li uid=' { { key } } ' { { val . name } }({ { val . count } })/Li
{% endfor %}
/ul
脚本src=' https://cdn . bootss.com/jquery/3 . 3 . 0/jquery . min . js '/脚本
脚本
$(function(){ 0
$('#userList ')。on('dblclick ',' li ',function(){ 0
v
ar 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="/uploads/allimg/211103/1134595537-1.jpg"></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>