轮询

ajax轮询 ,ajax轮询 的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

1、后端代码

from flask import Flask,render_template

app = Flask(__name__)

UUUU = {
'':{'name':'王','count':1},
'':{'name':'李','count':1},
'':{'name':'赵','count':1},
} @app.route('/index')
def index():
return render_template('index.html',user_list = UUUU) if __name__ == '__main__':
app.run()

2、前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>最帅的</title>
</head>
<body>
<ul>
{% for k,v in user_list.items() %}
<li>{{k}}: {{v.name}} {{v.count}} </li>
{% endfor %}
</ul>
<script>
# 重点2秒重新请求
function reload() {
window.location.reload()
}
setInterval(reload,2000) </script>
</body>
</html>

长轮询

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消        息才返回或超时,返回完之后,客户端再次建立连接,周而复始,基于事件的触发,一个事件接一个事件。

Ajax轮询与long poll都属于不断发送http请求,然后等待服务器处理,可以看到http协议一个特点,被动性,服务端不能主动联系客户端,只有客户端发起。

缺点:Ajax轮询需要服务器有很快的处理速度与快速响应。long poll需要很高的并发,体现在同时容纳请求的能力。

1、后端代码

from flask import Flask,render_template,request,session,redirect,jsonify
from uuid import uuid4
from queue import Queue,Empty
import json
app = Flask(__name__)
app.secret_key = "asdfasdfasdf"
UUUU = {
'':{'name':'王','count':1},
'':{'name':'李','count':1},
'':{'name':'赵','count':1},
} # 为每个登录用户保存
# dfasdfadsfasdfadf: Queue()
USER_QUEUE_DICT = { } @app.before_request
def check_login():
if request.path == '/login':
return None
user_info = session.get('user_info')
if not user_info:
return redirect('/login') @app.route('/login',methods=['GET','POST'])
def login():
if request.method == "GET":
return render_template('login.html')
else:
user = request.form.get('user')
nid = str(uuid4())
USER_QUEUE_DICT[nid] = Queue()
session['user_info'] = {'nid':nid, 'user':user }
return redirect('/index') @app.route('/index')
def index():
return render_template('index.html',user_list = UUUU) @app.route('/query')
def query():
"""每个用户查询最新投票信息"""
ret = {'status':True,'data':None}
current_user_nid = session['user_info']['nid']
queue = USER_QUEUE_DICT[current_user_nid]
try:
# {'uid':1, 'count':6}
ret['data'] = queue.get(timeout=10) #十秒后断开,再连
except Empty as e:
ret['status'] = False
# return jsonify(ret)
return json.dumps(ret) @app.route('/vote')
def vote():
"""
用户投票
:return:
"""
uid = request.args.get('uid')
old = UUUU[uid]['count']
new = old + 1
UUUU[uid]['count'] = new for q in USER_QUEUE_DICT.values():
q.put({'uid':uid, 'count':new}) return "投票成功" if __name__ == '__main__':
app.run(host='0.0.0.0',threaded=True)

2、前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>最帅</title>
</head>
<body>
<ul>
{% for k,v in user_list.items() %}
<li style="cursor: pointer;" ondblclick="doVote('{{k}}')" id="user_{{k}}">{{k}}: {{v.name}} <span>{{v.count}}</span> </li>
{% endfor %}
</ul>
<!--<script src="/static/jquery-1.12.4.js"></script>-->
<script src="{{ url_for('static',filename='jquery-1.12.4.js') }}"></script>
<script> $(function () {
get_data();
}) /*
查询最新信息
*/
function get_data() {
$.ajax({
url: '/query',
type:'GET',
dataType:'json',
success:function (arg) {
if(arg.status){
var liId = "#user_" + arg.data.uid;
$(liId).find('span').text(arg.data.count);
}
get_data();
} })
} /*
投票
*/
function doVote(uid) {
$.ajax({
url:'/vote', // /vote?uid=1
type:'GET',
data:{
uid:uid
},
success:function (arg) { }
})
}
</script>
</body>
</html>

websocket

webSocket是html5一种新的协议,实现了浏览器与服务器之间的全双工通信,能很好的节省服务器资源与带宽,并在服务器端与浏览器端实现实时通行,他建立在TCP之上, 同http一样,通过tcp来传输数据。

只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,服务器端会知道连接的信息,知道客户端关闭请求,同时由服务器主动推送,当有信息需要发送时,直接发送。客户端的连接通过session对象存储,能够实现实时推送。

1、安装

pip3 install gevent-websocket

2、后端代码

from flask import Flask,render_template,request,session,redirect,jsonify
import uuid
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
import json app = Flask(__name__)
app.secret_key = 'xfsdfqw' USERS = {
'':{'name':'王','count':0},
'':{'name':'李','count':0},
'':{'name':'赵','count':0},
} @app.before_request
def before_request():
if request.path == '/login':
return None
user_info = session.get('user_info')
if user_info:
return None
return redirect('/login') @app.route('/login',methods=['GET','POST'])
def login():
if request.method == "GET":
return render_template('login.html')
else:
uid = str(uuid.uuid4())
session['user_info'] = {'id':uid,'name':request.form.get('user')}
return redirect('/index') @app.route('/index')
def index():
return render_template('index.html',users=USERS) # 为每个登录用户保存socket字典
WS_DICT = { } @app.route('/message')
def message():
if request.environ.get('wsgi.websocket'):
ws = request.environ['wsgi.websocket']
# 1. 刚连接成功
uid = session.get('user_info').get('id')
WS_DICT[uid] = ws from geventwebsocket.websocket import WebSocket
while True:
# 2. 等待用户发送消息,并接受
message = ws.receive()
# 关闭:message=None
if not message:
del WS_DICT[uid]
break old = USERS[message]['count']
new = old + 1
USERS[message]['count'] = new data = {'user':message,'count':new} for k,v in WS_DICT.items():
# 3. 向客户端推送消息
v.send(json.dumps(data)) return "Connected!" if __name__ == '__main__':
http_server = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler)
http_server.serve_forever()

3、前端代码

#login
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<input type="text" name="user">
<input type="submit" value="提交">
</form>
</body>
</html>
# index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>投票系统</h1>
<a onclick="closeConn();">关闭连接</a>
<a onclick="createConn();">创建连接</a>
<ul>
{% for k,v in users.items() %}
<li id="user_{{k}}" ondblclick="vote('{{k}}')">{{v.name}} <span>{{v.count}}</span> </li>
{% endfor %} </ul> <script src="{{ url_for('static',filename='jquery-3.3.1.min.js')}}"></script>
<script> var socket = null; function socketInit() {
socket.onopen = function () {
/* 与服务器端连接成功后,自动执行 */
}; socket.onmessage = function (event) {
/* 服务器端向客户端发送数据时,自动执行 */
var response = JSON.parse(event.data); // {'user':1,'count':new}
var nid = '#user_' + response.user;
$(nid).find('span').text(response.count)
}; socket.onclose = function (event) {
/* 服务器端主动断开连接时,自动执行 */
}; } /*
我要投票
id:帅哥id
*/
function vote(id) { socket.send(id);
} function closeConn() {
socket.close()
}
function createConn() {
socket = new WebSocket("ws://127.0.0.1:5000/message");
socketInit();
}
</script>
</body>
</html>

python之轮询、长轮询、websocket的更多相关文章

  1. 使用轮询&长轮询实现网页聊天室

    前言 如果有一个需求,让你构建一个网络的聊天室,你会怎么解决? 首先,对于HTTP请求来说,Server端总是处于被动的一方,即只能由Browser发送请求,Server才能够被动回应. 也就是说,如 ...

  2. Tornado长轮询和WebSocket

    Http协议是一种请求响应式协议, 不允许服务端主动向客户端发送信息. 短轮询是一种简单的实现服务端推送消息的解决方案, 客户端以一定间隔自动向服务端发送刷新请求, 服务端返回要推送的消息作为响应. ...

  3. 了解轮询、长轮询、长连接、websocket

    业务开发中我们往往会有一些需要即时通信的场景,比如微信扫码登录.聊天功能. 下面这四种方式都可以实现即时通信. 轮询: 浏览器通过定时器每隔一段时间向服务器端发送请求,服务器端收到请求并响应请求.没有 ...

  4. 轮询、长轮询、长连接、websocket

    Web端即时通讯技术:即时通讯技术简单的说就是实现这样一种功能:服务器端可以即时地将数据的更新或变化反应到客户端,例如消息即时推送等功能都是通过这种技术实现的.但是在Web中,由于浏览器的限制,实现即 ...

  5. 长连接、短连接、长轮询和WebSocket

    //转发,格式待整理 2017-08-0519784View0 对这四个概念不太清楚,今天专门搜索了解一下,总结一下: 长连接:在HTTP 1.1,客户端发出请求,服务端接收请求,双方建立连接,在服务 ...

  6. Apollo 3 定时/长轮询拉取配置的设计

    前言 如上图所示,Apollo portal 更新配置后,进行轮询的客户端获取更新通知,然后再调用接口获取最新配置.不仅仅只有轮询,还有定时更新(默认 5 分钟一次).目的就是让客户端能够稳定的获取到 ...

  7. es6- Generator函数实现长轮询

    1.Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. 语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态.形式上,Gene ...

  8. http轮询,长轮询

    轮询,长轮询 轮询 轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源. 实例:适于小 ...

  9. 你想了解的轮询、长轮询和websocket都在这里了

    日常生活中,有很多需要数据的实时更新,比如群聊信息的实时更新,还有投票系统的实时刷新等 实现的方式有很多种,比如轮询.长轮询.websocket 轮询 轮询是通过设置页面的刷新频率(设置多长时间自动刷 ...

随机推荐

  1. ChemOffice Professional 16.0新增了哪些功能

    ChemOffice Professional 16.0是为终极化学和生物组件设计,可满足化学家和生物学家的需求.ChemOffice Professional帮助科学家有效地检索数据库,包括SciF ...

  2. 九度 1481 Is It A Tree?

    题目 给定一个有向图, 判断其是否是一棵树 要求 (1) 除了根节点外, 每个节点只有唯一的前驱 (2) 从根节点出发, 到任何节点有且只有一条路径 思路 1. 要求(1) 可以通过记录每个节点的前驱 ...

  3. POJ 1426 Find The Multiple(背包方案统计)

    Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose ...

  4. ios开发之--ZHPickView输出格式不出现 +0000

    这样写就不会输出 +0000了 NSDate *select = [_datePicker date]; NSDateFormatter *dateFormatter = [[NSDateFormat ...

  5. Gamma编码及Delta编码概述

    一.Elias Gamma Coding 即Gamma编码,是一种对正整数进行编码的统一编码,由Peter Elias发明.适用于预先无法获知最大编码整数的情况,而且小整数出现频率高,大整数出现频率低 ...

  6. JavaScript DOM 对象

    JavaScript DOM 对象   什么叫DOM,DOM是文档对象模型(Document Object Model,是基于浏览器编程(在本教程中,可以说就是DHTML编程)的一套API接口,W3C ...

  7. android基础---->发送和接收短信

    收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这项功能,而Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.今天我们开始自己创建一个简单的发送和接收短 ...

  8. Neutron SDN 手动实现手册

    安装架构介绍 本文旨在通过自己搭建类似neutron (openvswitch + gre) 实现SDN 的环境,学习了解其工作原理,模拟核心原理,比如:同一租户自定义网络 instance 互通,手 ...

  9. RabbitMQ的安装和使用Python连接RabbitMQ

    绪论 这里的环境使用的是Mac OS X系统,所有的配置和使用都是基于Mac OS X 和Python 2.7 以及对应的pika库的. RabbitMQ的安装和配置 安装部分 #brew insta ...

  10. 【BZOJ5085】最大 鸽巢原理

    [BZOJ5085]最大 Description 给你一个n×m的矩形,要你找一个子矩形,价值为左上角左下角右上角右下角这四个数的最小值,要你最大化矩形的价值. Input 第一行两个数n,m,接下来 ...