[英]Flask-SocketIO and SocketIO Client; Client Emit event doesn't trigger consistently
[英]WebSocket connection between reactjs Client and flask-socketio Server doesn't open
在我的項目中,我使用 React 前端和帶有 RESTful API 的 Flask 服務器。 基本功能是前端從服務器端獲取數據並顯示出來。 這很好用,但我想我會改進它,讓客戶端在服務器從其他地方接收到新數據時自動重新獲取。 我可以使用輪詢並每隔一段時間觸發一次獲取請求,但這似乎是 WebSockets 的完美用例。 因此,我試圖在服務器和客戶端之間實現一個 websocket 連接,當某些事件發生時,服務器會向客戶端發送一條消息。
我的服務器是用 Flask 用 python 編寫的,使用特定於 Flask 的 websocket 庫似乎是個好主意。 我最終使用了flask-socketio ,但我在使它工作時遇到了問題。 我的服務器相關部分如下:
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
... # Server functionality for receiving and storing data from elsewhere, not related to the websocket
# Handle the webapp connecting to the websocket
@socketio.on('connect')
def test_connect():
print('someone connected to websocket')
emit('responseMessage', {'data': 'Connected! ayy'})
# Handle the webapp connecting to the websocket, including namespace for testing
@socketio.on('connect', namespace='/devices')
def test_connect2():
print('someone connected to websocket!')
emit('responseMessage', {'data': 'Connected! ayy'})
# Handle the webapp sending a message to the websocket
@socketio.on('message')
def handle_message():
print('someone sent to the websocket')
# Handle the webapp sending a message to the websocket, including namespace for testing
@socketio.on('message', namespace='/devices')
def handle_message2():
print('someone sent to the websocket!')
@socketio.on_error_default # handles all namespaces without an explicit error handler
def default_error_handler(e):
print('An error occured:')
print(e)
if __name__ == '__main__':
socketio.run(app, debug=True, host='0.0.0.0')
對於前端,我最初也嘗試使用庫。 我去了react-websocket 。
<Websocket
url={'ws://localhost:5000'} // I also tried /devices at the end of this url
onMessage={() => console.log('Received message through websocket.')}
debug={true}
/>
但是,此解決方案在連接后立即斷開連接,這意味着出現問題。 不過,找出到底出了什么問題似乎是不可能的。 盡管debug={true}
但我在日志中沒有得到任何指示。 我沒有使用這個解決方案,而是為前端換用了一個更自定義的 WebSocket 解決方案:
componentDidMount() {
moment.locale('nb');
jsonRequest(irrelevant url).then(jsonResponse => {
... // Handle the results of the initial fetch
const socket = new WebSocket('ws://localhost:5000'); // I also tried /devices at the end of this url
socket.onopen = () => console.log('opened custom socket');
socket.onclose = () => console.log('closed custom socket');
socket.onmessage = e => console.log('got message');
socket.onerror = e => console.log('websocket error');
socket.addEventListener('open', function(event) {
console.log('sending');
socket.send('Hello Server!');
});
socket.addEventListener('message', function(event) {
console.log('Message from server ', event.data);
});
this.socket = socket;
this.setState(...);
});
}
The Rendering...
是我放在渲染函數最頂部的控制台語句。
所以在這兩種解決方案中,客戶端在連接后立即斷開 websocket 連接。 我的服務器也沒有注意到任何事情。 沒有事件處理程序觸發 - 不是@socketio.on('connect')
,不是@socketio.on('message')
,甚至不是@socketio.on_error_default
。 因此,我發現自己遇到了障礙。 我如何從這里調試? 可能是什么問題? 我在 Ubuntu 服務器上嘗試了完全相同的代碼,所以我不認為localhost 是問題所在。
您將 Socket.IO 與 WebSocket 混淆了。 Socket.IO 協議建立在 WebSocket 和 HTTP 之上。 您的連接失敗是因為您使用普通的 WebSocket 客戶端連接到 Socket.IO 服務器。 您需要使用 Socket.IO 客戶端,就像這樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.