如何修复代码 400,消息错误请求版本('客户端!')

问题描述 投票:0回答:1

我有一些代码,其中 arduino Esp8266 应该连接到 pi 4 上托管的 Flask 服务器 我可以让它们连接,但最终得到“192.168.1.20 - - [16/Aug/2023 12:08:59] 代码 400,消息错误请求版本('客户端!') 192.168.1.20 - - [16/Aug/2023 12:08:59] “这是一个 webSocket 客户端!” 400 - ”

我发布了下面除了index.html之外的所有代码。

非常感谢任何帮助

蟒蛇

import socket
from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit

app = Flask(__name__)
socketio = SocketIO(app)

# Store a list of discovered Arduino devices
discovered_devices = []

@app.route('/')
def index():
    hostname = 'arduino20'  # Replace with the actual hostname
    return render_template('index.html', discovered_devices=discovered_devices, hostname=hostname)

@app.route('/send_message', methods=['POST'])
def send_message():
    message = request.form['message']
    
    # Send the message to all discovered Arduino devices
    for device in discovered_devices:
        try:
            arduino_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            arduino_socket.connect((device['ip'], device['port']))
            arduino_socket.sendall((message + '\r').encode())  # Add '\r' to the end of the message
            arduino_response = arduino_socket.recv(1024).decode()
            arduino_socket.close()
            
            # Emit the Arduino response through WebSocket
            socketio.emit('arduino_response', {'response': arduino_response})

        except Exception as e:
            print(f"Error sending message to {device['ip']}: {str(e)}")
    
    return "Message sent to all discovered Arduino devices"

@socketio.on('connect')
def handle_connect():
    print('WebSocket client connected')
    # Emit the discovery event to all connected clients
    for device in discovered_devices:
        socketio.emit('discovery', {'hostname': device['hostname'], 'ip': device['ip'], 'port': device['port']})

@socketio.on('discovery')
def handle_discovery(data):
    # Add the discovered device to the list
    discovered_devices.append({'hostname': data['hostname'], 'ip': data['ip'], 'port': data['port']})
    print(discovered_devices)

if __name__ == '__main__':
    socketio.run(app, debug=False, host='0.0.0.0')

arduino ESP8266

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <WebSocketsClient.h>

const char* ssid = "ssid";
const char* password = "password ";
const char* serverAddress = "192.168.1.18"; // Replace with your Flask server IP
const int serverPort = 5000; // Use the appropriate port

WiFiClient wifiClient;
WebSocketsClient webSocket;

WiFiServer server(serverPort);

int LED = 5;
String receivedMessage;

void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  webSocket.begin(serverAddress, serverPort);
  webSocket.onEvent(webSocketEvent);

  // Get the last number of the IP address and use it as the hostname
  String ipString = WiFi.localIP().toString();
  int lastIndex = ipString.lastIndexOf('.');
  String lastNumber = ipString.substring(lastIndex + 1);
  String hostname = "arduino" + lastNumber;

  // Print out the IP address and port
  Serial.println("Arduino IP: " + ipString);
  Serial.println("Arduino Port: " + String(serverPort));

  // Initialize mDNS
  if (!MDNS.begin(hostname.c_str())) {
    Serial.println("Error setting up mDNS");
  } else {
    Serial.println("mDNS responder started with hostname: " + hostname);
  }

  server.begin();
}


void loop() {
  webSocket.loop();
  MDNS.update();
  WiFiClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        receivedMessage = client.readStringUntil('\r');
        Serial.println("Received message: " + receivedMessage);
        // Message processing
        commandBreakDown(receivedMessage);
        client.println(receivedMessage); // Send the received message back to the client
        delay(100);
        client.stop();
      }
    }
  }
}
void commandBreakDown(String message) {
  int spaceIndex = message.indexOf(' ');
  if (spaceIndex != -1) {
    String command = message.substring(0, spaceIndex);  // Extract the command
    // Check if the command is valid
    if (command.equals("C1")) {
      String valueStr = message.substring(spaceIndex + 1);  // Extract the value
      int value = valueStr.toInt();
      digitalWrite(LED, HIGH); // Turn the LED on
      delay(value);
      digitalWrite(LED, LOW); // Turn the LED off
    }
  }
}
//webSocketEvent stuff
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
  String discoveryMessage; // Declare the variable here

  switch(type) {
    case WStype_DISCONNECTED:
      Serial.println("WebSocket disconnected");
      break;
    case WStype_CONNECTED:
      Serial.println("WebSocket connected");
      // Build the discovery JSON object
      discoveryMessage = "{\"hostname\":\"arduino\", \"ip\":\"" + WiFi.localIP().toString() + "\", \"port\":" + String(serverPort) + "}";
      webSocket.sendTXT(discoveryMessage.c_str());
      break;
    case WStype_TEXT:
      Serial.printf("Received payload: %s\n", payload);
      // Handle text payload, if needed
      break;
  }
}

有关如何修复它的任何建议

flask websocket server esp8266
1个回答
1
投票

我认为这是您使用的 WebSocket 库的问题。 SocketIO 和 WebSocket 是半兼容的

来自 SocketIO 的文档

尽管 Socket.IO 确实在可能的情况下使用 WebSocket 进行传输,但它会向每个数据包添加额外的元数据。这就是为什么 WebSocket 客户端将无法成功连接到 Socket.IO 服务器,并且 Socket.IO 客户端也将无法连接到普通 WebSocket 服务器。

我认为这就是你在 Python 中得到的有效信息。

“这是一个 webSocket 客户端!” 400 -“...不是 SocketIo 客户端...走开

我在服务器/客户端(Node.js/ESP/Arduino)上都大量使用 WebSocket,并且它工作得很好(尽管 Arduino 库不同),但我不知道这是否是使用本机 WebSocket 的选项,或者您必须在服务器?

有一些 Arduino SocketIO 库 Socket.io-Esp-client 不知道它们有多好,但也许值得一看。

© www.soinside.com 2019 - 2024. All rights reserved.