Flask接口返回内容意外发送至WebSocket服务器的问题排查
Flask与WebSocket集成问题解析
问题根源:不是Flask的return直接发给WebSocket服务器
你看到的那条无type的消息,并非Flask的return语句直接发送给WebSocket服务器,问题出在客户端的index.js逻辑里:
因为你是用客户端JS每60秒触发/fetch-price-data的HTTP请求,而你的JS代码大概率在收到该请求的响应后,错误地把响应内容(也就是Flask返回的{"status": "Data sent to WebSocket server"})通过WebSocket连接发送给了Node.js的WebSocket服务器。
从server.js的日志可以验证:这条无type的消息结构完全匹配Flask的return内容,而Python端通过WebSocketClient.send_data_to_websocket发送的是带type: 'price_data'的结构化消息,不会触发这个警告。
解决方法:修正客户端JavaScript逻辑
检查你的index.js代码,找到发起/fetch-price-data请求的部分,确保不要把HTTP响应的内容通过WebSocket发送出去。
错误示例(问题所在)
setInterval(() => { fetch('/fetch-price-data') .then(res => res.json()) .then(data => { ws.send(JSON.stringify(data)); // 错误:将HTTP响应发给WebSocket }); }, 60000);
正确示例
setInterval(() => { fetch('/fetch-price-data') .then(res => res.json()) .then(data => { console.log(data.status); // 仅在客户端打印状态,不发送到WebSocket }); }, 60000);
关于Flask+WebSocket客户端用法的合理性
这种架构是可行的,但有优化空间:
- 性能优化:当前每次调用
send_data_to_websocket都会创建新的WebSocket连接,频繁建立/关闭连接会带来性能开销,建议复用连接(比如在WebSocketClient初始化时建立长连接,或者使用连接池)。 - 架构简化:如果业务场景允许,可以直接在Flask中集成WebSocket服务器(比如使用
Flask-SocketIO库),不需要单独维护Node.js的WebSocket服务器,减少架构复杂度。
附相关代码片段
Python端WebSocket客户端与Flask接口
class WebSocketClient: def __init__(self, url="ws://localhost:8081"): self.url = url self.ws = None def connect(self): """Establish connection to the WebSocket server and close immediately.""" try: self.ws = websocket.WebSocket() self.ws.connect(self.url) print(f"Connected to WebSocket server at {self.url}") self.ws.close() # Close the connection right after establishing it except Exception as e: print(f"Error connecting to WebSocket server: {e}") self.ws = None def send_data_to_websocket(self, df): """Send data to the WebSocket server.""" try: self.ws = websocket.WebSocket() self.ws.connect(self.url) print("Sending data to WebSocket...") json_data = df.to_json(orient="records") # Create a structured message with type and payload message = { 'type': 'price_data', 'payload': json.loads(json_data) # Convert JSON string to a Python object } # Send the structured message as a JSON string self.ws.send(json.dumps(message)) # Serialize the message back to JSON print("Data sent:", message) self.ws.close() except Exception as e: print(f"Failed to send data: {e}") @app.route('/fetch-price-data', methods=['GET']) def fetch_price_data(): print('Fetching price data.............................') df = get_price_data() ws_client = WebSocketClient() ws_client.send_data_to_websocket(df) return jsonify({"status": "Data sent to WebSocket server"}), 200
Node.js端WebSocket服务器代码
const express = require('express'); const WebSocket = require('ws'); const path = require('path'); const app = express(); const port = 8080; // For serving the HTML page // Serve static HTML file app.use(express.static(path.join(__dirname, 'public'))); // WebSocket server on port 8081 const wss = new WebSocket.Server({ port: 8081 }); // Broadcast to all WebSocket clients wss.broadcast = function broadcast(data) { wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(data); } }); }; // Listen for incoming WebSocket messages from Python wss.on('connection', function connection(ws) { console.log('WebSocket connection established'); ws.on('message', function incoming(data) { const jsonData = data.toString(); // Convert the buffer to string console.log('Received data from Python:', jsonData); try { const message = JSON.parse(jsonData); // Parse incoming message // Log parsed message structure console.log('Parsed message:', message) // Check the message type before broadcasting if (message.type) { // Broadcast the structured message to all connected clients wss.broadcast(jsonData); // Send as is if it's already structured } else { console.warn('Received a message without a type. Message will not be broadcasted.'); console.log('Message with warning: ', message) } } catch (error) { console.error('Error parsing incoming message:', error); } }); });
内容的提问来源于stack exchange,提问作者Ant
相关产品推荐
相关产品推荐

