個人狀況是服務端用Flask,前端用Vue.js。問題都出在Flask上。前端
這個問題令我很不愉快,是由於寫法的問題致使的。實際上我在實例化SocketIO時已經傳入cors_allowed_origins的參數爲*,可是最後的問題出在*要用單引號,不能用雙引號。我以爲這多是先後傳參符號不一致致使的,應該不是必需要求寫單引號。nginx
# 錯誤的寫法 socketio = SocketIO(app, cors_allowed_origins="*", async_mode='eventlet') # 正確的寫法 socketio = SocketIO(app, cors_allowed_origins='*', async_mode='eventlet')
這個須要配置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,完美
在請求頭裏的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
報錯信息以下cors
TypeError: wrap_socket() got an unexpected keyword argument '_context'
這個是eventlet的鍋,Python3.7版本就會有這個bug。可是Flask-SocketIO推薦用eventlet。中文圈的資料都是說換個參數,換個什麼參數也沒說明白。國外的資料說把Python改爲3.6或者3.8就行。socket