Клиент Websocket STM32 ESP8266 получает неверный запрос HTTP/1.1 400 от сервера

#websocket #server #iot #esp8266 #stm32f0

Вопрос:

Я работаю над небольшим проектом интернета вещей на микроконтроллере STM32F070, подключенном к модулю Wi-Fi ESP8266. Я разработал клиентское приложение Websocket на контроллере STM32F070, которое будет взаимодействовать с удаленным сервером Websocket и обмениваться данными по соединению.

Я устанавливаю TCP-соединение с сервером от клиента Websocket, но после отправки заголовков запроса Websocket я получаю HTTP/1.1 400 Неверный запрос от сервера, и соединение ЗАКРЫВАЕТСЯ.

Вот журналы из линии ESP8266 UART:

 ready
WIFI CONNECTED
WIFI GOT IP
AT

OK
ATE0

OK

OK
WIFI DISCONNECT
WIFI CONNECTED
WIFI GOT IP

OK
 CIFSR:STAIP,"192.168.43.194"
 CIFSR:STAMAC,"48:3f:da:66:cf:2c"

OK

OK

ERROR
CLOSED

ERROR
CLOSED
CONNECT

OK

OK
>
Recv 227 bytes

SEND OK

 IPD,103:HTTP/1.1 400 Bad Request
Connection: close
Content-Type: text/html
Content-Length: 11

Bad RequestCLOSED
 

Вот заголовки, которые я отправляю на удаленный сервер Websocket

 AT RST
AT
ATE0
AT CWMODE=1
AT CWJAP="Txxxxx","08080808"
AT CIFSR
AT CIPMUX=0
AT CIPSTART="TCP","192.168.43.69",8080
AT CIPSEND=227
GET / HTTP/1.1
Host: 192.168.43.69:8080
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: NhEEf0jUzTLT3ZC2jSW1PnsX
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
 

ИЗМЕНИТЬ: Исходный код STM32F070 для отправки заголовков Websocket на сервер через ESP8266

     // 1) Generating WebSocket Header:

//Generate a random key.
Base64_GetRandomKey( webSock.LocalKey );

//Reset the flag so we can check in response.
webSock.ServerKeyOK = 0;

//Host IP:
ip3 = ( dev.NetServerIP_Addr >> 24 ) amp; 0xFF;
ip2 = ( dev.NetServerIP_Addr >> 16 ) amp; 0xFF;
ip1 = ( dev.NetServerIP_Addr >> 8 ) amp; 0xFF;
ip0 = ( dev.NetServerIP_Addr ) amp; 0xFF;

//Make the HTML headers.
len  = snprintf( amp;buf[len], HTTP_BUFFER_LEN_MAX - len, ( HTTP_PAGE_QUERY_REM_SRV_GET_HDR ), ip3, ip2, ip1, ip0, dev.NetServerPort );

len  = snprintf( amp;buf[len], HTTP_BUFFER_LEN_MAX - len, ( HTTP_PAGE_QUERY_REM_SRV_GET_BODY ), webSock.LocalKey );

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 2) Send Data Header to ESP8266, send Data Length with AT CIPSEND AT Command

//Send the IP data header during data send.
static void ESP8266_SendDataHeader( ESP_Con *connection )
{
    char buf[64];
    sprintf( buf, "AT CIPSEND=%drn", connection->IPD_Len );
    Esp8266TransmitWith( buf );
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// 3) Send Data after getting '>' char from ESP8266

//Wait for the data prompt.
len = FIFO2_GetCharsUntil( amp;espUsart.rxFIFO, esp.buffer, ESP_DATA_BUFFER_LEN, '>' );
if( len > 0 amp;amp; strstr( esp.buffer, ( ">" ) ) != NULL )      //Got the prompt to send data.
{
    esp.timeout = EspConnectionTimeOutMed;
    FIFO2_Flush(amp;espUsart.rxFIFO, 0 );
    esp.state = EspStateSendDataReady;
}
else if( esp.timeout > ESP_TASK_INTERVAL )
{
    esp.timeout -= ESP_TASK_INTERVAL;
}
else if( esp.retry > ESP_SEND_DATA_RETRY_MAX )
{
    esp.state = EspStateIpClose;
}
else
{
    esp.state = EspStateSendData;
    // Sending Header Data to ESP8266 from Here
}
 

HTTP Headers from Source Code:

 "GET / HTTP/1.1rnHost: %d.%d.%d.%d:%drn"
"Connection: Upgradern"
"Upgrade: websocketrn"
"Sec-WebSocket-Version: 13rn"
"Sec-WebSocket-Key: %srn"
"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bitsrnrn"
 

Here is WebSocket Server Code in Node Js.

 var bodyParser = require("body-parser");
const express = require('express'); //express framework to have a higher level of methods
const app = express(); //assign app variable the express class/method
var http = require('http');
var path = require("path");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const server = http.createServer(app);//create a server


//***************this snippet gets the local ip of the node.js server. copy this ip to the client side code and add ':3000' *****
//****************exmpl. 192.168.56.1---> var sock =new WebSocket("ws://192.168.56.1:3000");*************************************
require('dns').lookup(require('os').hostname(), function (err, add, fam) {
  console.log('addr: ' add);
})

/**********************websocket setup**************************************************************************************/
//var expressWs = require('express-ws')(app,server);
const WebSocket = require('ws');
const s = new WebSocket.Server({ server });

s.on('connection', function(ws, req) {
  console.log(req.headers);
  console.log(req.params);
});

//when browser sends get request, send html file to browser
// viewed at http://localhost:30000
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname   '/index.html'));
});


//*************************************************************************************************************************
//***************************ws chat server********************************************************************************

//app.ws('/echo', function(ws, req) {
s.on('connection',function(ws,req){

/******* when server receives messsage from client trigger function with argument message *****/
ws.on('message',function(message){
console.log("Received: " message);
s.clients.forEach(function(client){ //broadcast incoming message to all clients (s.clients)
if(client!=ws amp;amp; client.readyState ){ //except to the same client (ws) that sent this message
client.send("broadcast: "  message);
}
});
// ws.send("From Server only to sender: "  message); //send to client where message is from
});
ws.on('close', function(){
console.log("lost one client");
});
//ws.send("new client connected");
console.log("new client connected");
});
server.listen(8080);
 

Сервер NodeJS WebSocket тестируется с помощью мобильного приложения WebSocketClient Tester для Android. Он отлично работает

ПРАВКА 2:

Я попытался подключиться http://echo.websocket.org/, Я изменил код для подключения к http://echo.websocket.org/. Я могу успешно связаться с http://echo.websocket.org/. Получен ответ от http://echo.websocket.org/

вот журналы для справки.

чтобы http://echo.websocket.org/

 GET / HTTP/1.1
Host: echo.websocket.org
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: Dh6EV0ZUpTBTtZ42ZSM1FniX
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
 

от http://echo.websocket.org/

  IPD,201:HTTP/1.1 101 Web Socket Protocol Handshake
Connection: Upgrade
Date: Sun, 23 May 2021 08:54:52 GMT
Sec-WebSocket-Accept: TaHsjyffJhTaBluq4Bmksq0NPWo=
Server: Kaazing Gateway
Upgrade: websocket
 

Комментарии:

1. у вас есть пустая строка после заголовков http?

2. Нет, после заголовков нет пустых строк.

3. протокол HTTP требует, чтобы после заголовков была пустая строка

4. ох, моя беда, после HTTP-заголовков есть пустая строка. Отредактированный вопрос

5. Опубликуйте свой код stm32, свой node.js код не имеет значения, если вы уже протестировали его с помощью приложения для Android.