flask使用socketio的比較多,感覺直接使用socket更簡單,下面是介紹如何使用flask_sockets的(不是socketio哦)。
- 一、下載安裝模塊
1.安裝flask:pip install flask
2.安裝flask_sockets:pip install flask-sockets
3.安裝gevent:pip install gevent
- 二、配置flask
先上完整代碼:
from flask import Flask, request
from flask_sockets import Sockets
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
import time,json
app = Flask(__name__)
sockets=Sockets(app)
#服務端ws://127.0.0.1:8080/webSocket
@sockets.route('/webSocket', methods=["POST","GET"])
def webSocket(self): #這個self必須加,不然會報錯
lastres=""
if request.environ.get("wsgi.websocket"):
ws=request.environ["wsgi.websocket"]
while 1:
msg={"wsmsg":"message from flask websocket at %s"%(time.strftime("%Y-%m-%d,%H:%M:%S"))}
ws.send(json.dumps(msg)) #網絡傳輸一般都用json字符串格式
time.sleep(1)
return
#客戶端,http://127.0.0.1:8080/socketshow
@app.route('/socketshow', methods=["POST","GET"])
def socketshow():
html=""" <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask Websocket示例</title>
</head>
<body>
<div>
<h2> Flask websocket example</h2>
<p id="websocketmsg"></p>
</div>
<script type="text/javascript">
var websocket = null;
//判斷當前瀏覽器是否支持WebSocket
if ("WebSocket" in window) {
websocket = new WebSocket("ws://localhost:8080/webSocket"); //這里就是這個服務端了
} else {
alert("websocket連接失敗!!刷新頁面");
setMessageInnerHTML(JSON.stringify({ error: "連接失敗" }));
}
//連接發生錯誤的回調方法
websocket.onerror = function () {
alert("subject連接失敗!!刷新頁面");
setMessageInnerHTML(JSON.stringify({ error: "error" }));
};
//連接成功建立的回調方法
websocket.onopen = function (event) {
setMessageInnerHTML(JSON.stringify({ key: "webSocket 連接成功~" }));
};
//接收到消息的回調方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
};
//連接關閉的回調方法
websocket.onclose = function () {
setMessageInnerHTML("close");
};
//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,
// 防止連接還沒斷開就關閉窗口,server端會拋異常。
window.onbeforeunload = function () {
websocket.close();
};
//將消息顯示在網頁上
function setMessageInnerHTML(innerHTML) {
var result = JSON.parse(innerHTML);
//console.log(result);
if (result) {
document.getElementById("websocketmsg").innerHTML =result.wsmsg;
}
}
//關閉連接
function closeWebSocket() {
websocket.close();
}
</script>
</body>
</html>
"""
return html
if __name__ == '__main__':
#app.run(host="0.0.0.0",port=8093,debug=True) #外網訪問需要開端口+host設置為0.0.0.0
server=pywsgi.WSGIServer(("0.0.0.0",8080),app,handler_class=WebSocketHandler)
print("serving flask socket at 0.0.0.0:8080")
server.serve_forever()
- 三、調bug
運行時flask 1以上的版本客戶端連接時會報錯,WebsocketMismatch
werkzeug.routing.WebsocketMismatch: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.

這個可能是wekzeug檢查網址有效性太嚴格了,可以修改site-packages\werkzeug\routing.py代碼,把raise WebsocketMismatch()的觸發條件注釋掉就可以了。
一般的IDE,比如vscode,pycharm都支持點擊報錯跳轉到出錯的文件,很好找的。

可以看到raise WebsocketMismatch()的觸發條件是websocket_mismatch為True,那只要把它=True注釋掉就可以了,
在werkzeug\routing.py搜索websocket_mismatch,可以找到:

把1999行-2001行 這段注釋掉
這樣就可以了。
另一個可能的bug:
注意服務端的webSocket函數必須加self,因為WebsocketHandler要用self指向這個實例觸發事件。
如果不加self,會報TypeError: webSocket() takes 0 positional arguments but 1 was given

- 四、網頁端結果
每秒刷新一次。