python+html实现 轮询 长轮询 websocket 服务端+客户端 本文共有7906个字,关键词: 当我们要实现一个实时投票系统,或者是实时通讯系统,我们的页面数据总需要更新~~ 我们不能让用户一直去刷新页面~所以有了轮询,长轮询,以及websock的出现~~ ###轮询 既然我想要实时获取后端的数据,那我就每隔2秒给后端发一次请求~~ 这种我们就叫轮询~那它会有一些缺点就是存在延时~就算每秒发一次~也会存在一定的延迟~~ 我们看下轮询的实现~~ ####app.py ``` # by gaoxin from flask import Flask, render_template, request, jsonify app = Flask(__name__) USERS = { 1: {"name": "苑昊", "count": 0}, 2: {"name": "苑昊2", "count": 0}, 3: {"name": "苑昊3", "count": 0}, } @app.route("/") def index(): return render_template("index.html", users=USERS) @app.route("/vote", methods=["POST"]) def vote(): uid = request.json.get("uid") USERS[uid]["count"] += 1 return "投票成功" @app.route("/get_vote") def get_vote(): return jsonify(USERS) if __name__ == '__main__': app.run() ``` ####client.html ``` Title 跟老男孩最丑的老师投票 {% for key, value in users.items()%} {{value.name}} ({{value.count}}) {% endfor %} index.html ``` ###长轮询 轮询缺点就是延迟~那么如果前端发送过来请求~如果没有数据的更新~ 后端就夯住请求~直到有数据返回或者超时再返回~这样延迟就可以得到很好的解决~~ python中有个queue对象~~ 当我们从这个队列里拿不到值的时候~可以夯住请求的~~~ ####queueDemo.py ``` # by gaoxin import queue from flask import Flask app = Flask(__name__) q = queue.Queue() @app.route("/get") def index(): try: val = q.get(timeout=20) except queue.Empty: val = "超时" return val @app.route("/vote") def vote(): q.put("10") return "投票成功" if __name__ == '__main__': app.run() queueDemo.py ``` 如果我为每个请求都建立一个q对象~~ 然后夯住他们的请求~有数据更新的时候~给他们的q对象返回值就可以了~ ####server.py ``` # by gaoxin from flask import Flask, render_template, request, jsonify, session import queue import uuid app = Flask(__name__) app.secret_key = "lajdgia" USERS = { 1: {"name": "苑昊", "count": 0}, 2: {"name": "苑昊2", "count": 0}, 3: {"name": "苑昊3", "count": 0}, } # 为每个用户建立一个q对象 # 以用户的uuid为key 值为q对象 Q_DICT = {} @app.route("/") def index(): user_uuid = str(uuid.uuid4()) session["user_uuid"] = user_uuid Q_DICT[user_uuid] = queue.Queue() return render_template("index2.html", users=USERS) @app.route("/vote", methods=["POST"]) def vote(): # 投票 循环q对象的dict 给每个q对象返回值 uid = request.json.get("uid") USERS[uid]["count"] += 1 for q in Q_DICT.values(): q.put(USERS) return "投票成功" @app.route("/get_vote", methods=["POST", "GET"]) def get_vote(): # 获取投票结果 去自己的q对象里取值 没有夯住 知道有或者超时返回 user_uuid = session.get("user_uuid") q = Q_DICT[user_uuid] try: users = q.get(timeout=30) except queue.Empty: users = "" return jsonify(users) if __name__ == '__main__': app.run() app2.py ``` ####client.html ``` Title 跟老男孩最丑的老师投票 {% for key, value in users.items()%} {{value.name}} ({{value.count}}) {% endfor %} index2.html ``` ###websocket websocket是一个协议~~ 协议规定~ 连接的时候需要握手~~ 发送的数据需要加密~~ 连接之后不断开~~ Flask不带websocket,我们需要下载~ pip install gevent-websocket ####server.py ``` # by gaoxin from flask import Flask, request, render_template from geventwebsocket.handler import WebSocketHandler from gevent.pywsgi import WSGIServer import json app = Flask(__name__) USERS = { 1: {"name": "苑昊", "count": 0}, 2: {"name": "苑昊2", "count": 0}, 3: {"name": "苑昊3", "count": 0}, } @app.route("/") def index(): return render_template("index3.html", users=USERS) WEBSOCKET_LIST = [] @app.route("/vote") def vote(): ws = request.environ.get("wsgi.websocket") if not ws: return "HTTP请求" WEBSOCKET_LIST.append(ws) while True: uid = ws.receive() if not uid: WEBSOCKET_LIST.remove(ws) ws.close() break uid = int(uid) USERS[uid]["count"] += 1 name = USERS[uid]["name"] new_count = USERS[uid]["count"] for client in WEBSOCKET_LIST: client.send(json.dumps({"uid": uid, "name": name, "count": new_count})) if __name__ == '__main__': http_server = WSGIServer(('127.0.0.1', 5000), app, handler_class=WebSocketHandler) http_server.serve_forever() app3.py ``` ####client.html ``` Title 最丑的男人投票系统 {% for (key, value) in users.items() %} {{value.name}} ({{value.count}}) {% endfor%} index3.html ``` × yihong (๑>ڡ<)☆谢谢老板~ 2元 5元 10元 50元 100元 任意金额 2元 使用微信扫描二维码完成支付 版权声明:本文为作者原创,如需转载须联系作者本人同意,未经作者本人同意不得擅自转载。 Python 2019-10-22 1 条评论 6392 次浏览
(!)[zface_2.png]