ajax輪詢 ,ajax輪詢 的原理很是簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。html
一、後端代碼前端
from flask import Flask,render_template app = Flask(__name__) UUUU = { '1':{'name':'王','count':1}, '2':{'name':'李','count':1}, '3':{'name':'趙','count':1}, } @app.route('/index') def index(): return render_template('index.html',user_list = UUUU) if __name__ == '__main__': app.run()
二、前端代碼html5
<!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給客戶端。直到有消 息才返回或超時,返回完以後,客戶端再次創建鏈接,周而復始,基於事件的觸發,一個事件接一個事件。 jquery
Ajax輪詢與long poll都屬於不斷髮送http請求,而後等待服務器處理,能夠看到http協議一個特色,被動性,服務端不能主動聯繫客戶端,只有客戶端發起。web
缺點:Ajax輪詢須要服務器有很快的處理速度與快速響應。long poll須要很高的併發,體如今同時容納請求的能力。ajax
一、後端代碼json
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 = { '1':{'name':'王','count':1}, '2':{'name':'李','count':1}, '3':{'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)
二、前端代碼flask
<!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是html5一種新的協議,實現了瀏覽器與服務器之間的全雙工通訊,能很好的節省服務器資源與帶寬,並在服務器端與瀏覽器端實現實時通行,他創建在TCP之上, 同http同樣,經過tcp來傳輸數據。後端
只須要一次HTTP握手,因此說整個通信過程是創建在一次鏈接/狀態中,服務器端會知道鏈接的信息,知道客戶端關閉請求,同時由服務器主動推送,當有信息須要發送時,直接發送。客戶端的鏈接經過session對象存儲,可以實現實時推送。瀏覽器
一、安裝
pip3 install gevent-websocket
二、後端代碼
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 = { '1':{'name':'王','count':0}, '2':{'name':'李','count':0}, '3':{'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()
三、前端代碼
#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>