mobizt / ESP_SSLClient

The upgradable Secure Layer Networking (SSL/TLS) TCP Client for Arduino devices that support external networking interfaces e.g., WiFiClient, EthernetClient, and GSMClient.
MIT License
21 stars 4 forks source link

Does not keep connection open #6

Closed rjjrbatarao closed 4 months ago

rjjrbatarao commented 4 months ago

Hi amazing work for this library, I've implemented a server sent event client on esp32 and esp8266 its working fine on WifiSecureClient but when I change it to this ESP_SSLClient Implementation it keeps on disconnecting after the connection failing to send the Connection: keep-alive required by servent sent events.

rjjrbatarao commented 4 months ago

Here is the minimal example

#include <Arduino.h>
#include <WiFi.h>
#include <ESP_SSLClient.h>

ESP_SSLClient ssl_client;
WiFiClient basic_client;

void connect_server(ESP_SSLClient *ssl)
{
    if (!ssl->connect("127.0.0.1", 443))
    {
        return;
    }
    else
    {
        Serial.println(">>> Connection Successful !");
    }
    // fails to send this connection is closed after the connection
    String footer = String(" HTTP/1.1\r\n") + "Host: " + "127.0.0.1" + "\r\n" + "Accept: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "Connection: keep-alive\r\n\r\n";
    ssl->print("GET /events" + footer);
}

void read_response(ESP_SSLClient *ssl)
{
    unsigned long timeout = millis();
    while (!ssl->connected())
    {
        yield();
        if (millis() - timeout > 5000)
        {
            Serial.printf("\nClosing connection\n\n");
            Serial.println(">>> Client Timeout !");
            ssl->stop();
            connect_server(ssl);
            return;
        }
    }
    while (ssl->available())
    {
        String line = ssl->readStringUntil('\r');
        yield();
        if (validate_json(line.c_str()))
        {
            line.trim();
            line.replace("data: ", "");
            Serial.print(line);
        }
        else
        {
            Serial.print(line);
        }
    }
}

void setup()
{
    Serial.begin(115200);
    ssl_client.setInsecure();
    ssl_client.setDebugLevel(1);
    ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */);
    ssl_client.setClient(&basic_client);
}

void loop()
{
    read_response(&ssl_client);
}
mobizt commented 4 months ago

In your case the WiFiClient (or NetworkClient in ESP32 core v3.0.x) was stopped because the sever closes the connection instead.

I test with the simple SSE server PHP script and the Arduino sketch below, and everything is ok.

// sse.php
<?php

set_time_limit(600);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

while (true) {

    $time = date('r');
    echo "data: The server time is: {$time}\n\n";

    if (ob_get_level() > 0) {
        ob_flush();
    }

    flush();

    if (connection_aborted()) {
        return;
    }

    sleep(2);
}
?>

#include <Arduino.h>
#include <WiFi.h>

#include <ESP_SSLClient.h>

#define WIFI_SSID "WIFI_AP"
#define WIFI_PASSWORD "WIFI_PASSWORD"

ESP_SSLClient ssl_client;

WiFiClient basic_client;

String host = "your_ip_or_host";
String uri = "/sse.php";
uint16_t port = 443;

bool connect()
{
    Serial.println();
    Serial.print("Connecting to server...");

    if (ssl_client.connect(host.c_str(), port))
    {
        Serial.println(" ok");

        String header = "GET ";
        header += uri;
        header += " HTTP/1.1\r\n";
        header += "Host: ";
        header += host;
        header += "\r\n\r\n";

        int ret = ssl_client.print(header);
        return ret == header.length();
    }
    else
    {
        ssl_client.stop();
        Serial.println(" failed\n");
        delay(2000);
    }

    return false;
}

void setup()
{
    Serial.begin(115200);

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    Serial.print("Connecting to Wi-Fi");
    unsigned long ms = millis();
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(300);
    }
    Serial.println();
    Serial.print("Connected with IP: ");
    Serial.println(WiFi.localIP());
    Serial.println();

    ssl_client.setInsecure();
    ssl_client.setBufferSizes(1024, 512);
    ssl_client.setDebugLevel(1);
    ssl_client.setClient(&basic_client);

    connect();
}

void loop()
{
    if (!ssl_client.connected() && !connect())
        return;

    while (ssl_client.connected() && ssl_client.available())
    {
        Serial.print(ssl_client.readStringUntil('\r'));
    }
}
rjjrbatarao commented 4 months ago

Thank you for the example it works, the problem now is when I tried changing my sse server port from 443 to 8443 or 5443 also same with the example code then it fails to send, but I got connect ok message.

mobizt commented 4 months ago

It is your server problems not a library problem.

Ok I got your issue of custom ports.