Skip to main content
 首页 » 编程设计

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

2025年05月04日54lyhabc

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

我的服务器是用 python 和 Flask 编写的,使用特定于 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(...); 
    }); 
} 

这个解决方案有同样的问题。我的控制台输出如下:

Rendering... 是我放在渲染函数最顶部的控制台语句。

所以在这两种方案中,客户端连接后立即断开websocket连接。我的服务器也没有注意到任何东西。没有一个事件处理程序触发 - 不是 @socketio.on('connect'),不是 @socketio.on('message') 甚至 @socketio .on_error_default。因此,我发现自己遇到了障碍。我如何从这里调试?可能是什么问题?我在 Ubuntu 服务器上尝试过完全相同的代码,所以我认为本地主机不是问题。

请您参考如下方法:

您将 Socket.IO 与 WebSocket 混淆了。 Socket.IO 协议(protocol)建立在 WebSocket 和 HTTP 之上。您的连接失败是由于您使用普通的 WebSocket 客户端连接到 Socket.IO 服务器造成的。你需要使用 Socket.IO 客户端,比如 this one .