Flask websocket

websocket

概念

是一套協議,協議規定了:html

  - 鏈接時須要握手前端

  - 發送數據進行加密jquery

  - 鏈接以後不斷開web

意義

  實現長輪詢等操做django

框架支持

- flask,gevent-websocketjson

- django,channelflask

- torando框架自帶後端

應用場景

實時響應頁面時,能夠使用websocket。服務器

缺點

兼容性比較差,版本較低的IE沒法支持websocket

使用方法

導入

from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer

啓動

Flask 的啓動的地方改爲這樣便可以支持 websocket ,同時並不會覆蓋 http ,二者並存

if __name__ == '__main__':
    http_server = WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler)
    http_server.serve_forever()

後端操做

ws = request.environ.get('wsgi.websocket')  # 要拿到websocket 的標識才能夠操做

msg = ws.receive() # 從客戶端接收消息

ws.send("你好啊") # 向客戶端發送消息

前端操做

var ws = new WebSocket('ws://127.0.0.1:5000/message')    // 不定義的話默認就是 HTTP,定義後往指定的url 發起 websocket 連接請求


ws.onmessage
= function (event) {  // 服務器端向客戶端發送數據時,自動執行 var response = JSON.parse(event.data);    // 接收服務端的數據 };


ws.send("你好呀")   // 向服務端發送消息
 

示例

前端

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <h1>醜男投票系統</h1>
    <ul>
        {% for k,v in users.items() %}
            <li onclick="vote({{k}})" id="id_{{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 ws = new WebSocket('ws://127.0.0.1:5000/message')
        ws.onmessage = function (event) {
            /* 服務器端向客戶端發送數據時,自動執行 */
            // {'cid':cid,'count':new}
            var response = JSON.parse(event.data);
            $('#id_'+response.cid).find('span').text(response.count);

        };

        function vote(cid) {
            ws.send(cid)  // 發送信息
        }
    </script>
</body>
</html>

後端

from flask import Flask,render_template,request
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
import json

app = Flask(__name__)

USERS = {
    '1':{'name':'鋼彈','count':0},
    '2':{'name':'鐵錘','count':0},
    '3':{'name':'貝貝','count':100},
}


# http://127.0.0.1:5000/index
@app.route('/index')
def index():
    return render_template('index.html',users=USERS)

# http://127.0.0.1:5000/message
WEBSOCKET_LIST = []
@app.route('/message')
def message():
    ws = request.environ.get('wsgi.websocket')
    if not ws:
        print('http')
        return '您使用的是Http協議'
    WEBSOCKET_LIST.append(ws)
    while True:
        cid = ws.receive()  # 接收信息
        if not cid:
            WEBSOCKET_LIST.remove(ws)
            ws.close()
            break
        old = USERS[cid]['count']
        new = old + 1
        USERS[cid]['count'] = new
        for client in WEBSOCKET_LIST:
            client.send(json.dumps({'cid':cid,'count':new}))



if __name__ == '__main__':
    http_server = WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler)
    http_server.serve_forever()
相關文章
相關標籤/搜索