我有一些代码,其中 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;
}
}
有关如何修复它的任何建议
我认为这是您使用的 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 不知道它们有多好,但也许值得一看。