Flask-SocketIO部署遇到的問題

個人狀況是服務端用Flask,前端用Vue.js。問題都出在Flask上。前端

CORS跨域問題

這個問題令我很不愉快,是由於寫法的問題致使的。實際上我在實例化SocketIO時已經傳入cors_allowed_origins的參數爲*,可是最後的問題出在*要用單引號,不能用雙引號。我以爲這多是先後傳參符號不一致致使的,應該不是必需要求寫單引號。nginx

# 錯誤的寫法
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet')
# 正確的寫法
socketio = SocketIO(app, cors_allowed_origins='*', async_mode='eventlet')

400錯誤

這個須要配置Nginx,參考了一篇帖子,配置以下git

location /
{
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

其中第一行是告訴nginx使用HTTP/1.1通訊協議,這是websoket必需要使用的協議。github

第二行和第三行告訴nginx,當它想要使用WebSocket時,響應http升級請求。web

最後發現400仍然存在,在Vue.js上取消輪詢polling,只留websocket,完美

Websocket沒有請求頭

在請求頭裏的JWT信息就失效了,國外資料是推薦把token放在query裏。服務端接收到token解碼。跨域

# 個人token格式是Bearer+空格+token,因此把token分割出來
data = decode_token(encoded_token=YourToken.split(' ', 1)[1])
# 用戶id就包含在解碼的數據裏面
uid = data['identity']['uid']

用戶id就包含在解碼的數據裏面,具體能夠了解一個JWT的原理,JWT的格式是頭部.負載.簽名(header+payload+signature),負載是能夠存儲信息的,uid就在裏頭。websocket

數據返回慢

這個是不認真看文檔的後果,gunicorn啓動時,官方推薦worker_class用eventlet。app

POST方法接收不到數據

報錯信息以下cors

TypeError: wrap_socket() got an unexpected keyword argument '_context'

這個是eventlet的鍋,Python3.7版本就會有這個bug。可是Flask-SocketIO推薦用eventlet。中文圈的資料都是說換個參數,換個什麼參數也沒說明白。國外的資料說把Python改爲3.6或者3.8就行。socket

參考資料:

  1. 400錯誤解決方法
  2. 400錯誤官方issue
  3. 400錯誤原理解釋
  4. eventlet在Python3.7上的Bug
相關文章
相關標籤/搜索