WebSocket与reactjs客户端和flask-socketio之间的连接服务器未打开

问题描述:

在我的项目中,我正在使用React前端和带有RESTful API的Flask服务器。基本功能是前端从服务器获取数据并显示它。这工作正常,但我想通过让客户端自动重新获取服务器从其他地方接收新数据时,我会改进它。我可以使用轮询,并间隔地发起一个获取请求,但这看起来像是WebSockets的完美用例。因此,我试图在服务器和客户端之间实现一个websocket连接,当某些事件发生时,服务器向客户端发送消息。WebSocket与reactjs客户端和flask-socketio之间的连接服务器未打开

我的服务器是用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(...); 
    }); 
} 

此解决方案具有相同的问题。我的控制台输出如下: console output

Rendering...是我放在我的渲染功能的顶部的控制台声明。

因此,在这两种解决方案中,客户端在连接后立即断开与websocket的连接。我的服务器也没有注意到任何东西。没有事件处理程序触发 - 不是@socketio.on('connect'),而不是@socketio.on('message'),甚至不是@socketio.on_error_default。因此,我发现自己处于障碍之中。我如何从这里调试?这个问题会是什么?我已经在Ubuntu服务器上尝试过相同的确切代码,所以我不认为是localhost是问题。

您正在使用WebSocket混淆Socket.IO。 Socket.IO协议建立在WebSocket和HTTP之上。您使用普通WebSocket客户端连接到Socket.IO服务器导致连接失败。您需要使用Socket.IO客户端,如this one